yasme/src/main/java/de/fau/cs/mad/yasme/android/ui/AbstractYasmeActivity.java
public abstract class AbstractYasmeActivity extends Activity implements Toastable {
    public final static String USER_ID = "de.fau.cs.mad.yasme.android.USER_ID";
    public final static String USER_NAME = "de.fau.cs.mad.yasme.android.USER_NAME";
    public final static String USER_MAIL = "de.fau.cs.mad.yasme.android.USER_MAIL";
    public final static String USER_PW = "de.fau.cs.mad.yasme.android.USER_PW";
    public final static String DEVICE_ID = "de.fau.cs.mad.yasme.android.DEVICE_ID";
    public final static String PROFILE_PICTURE = "de.fau.cs.mad.yasme.android.PROFILE_PICTURE";

    public final static String CHAT_ID = "de.fau.cs.mad.yasme.android.CHAT_ID";
    public final static String LAST_MESSAGE_ID = "de.fau.cs.mad.yasme.android.LAST_MESSAGE_ID";

    public final static String ACCESSTOKEN = "de.fau.cs.mad.yasme.android.ACCESSTOKEN";
    public final static String SIGN_IN = "de.fau.cs.mad.yasme.android.SIGN_IN";

    public final static String SERVERINFOUPDATETIME = "de.fau.cs.mad.yasme.android.SERVERINFOUPDATETIME";
    public final static String SERVERMESSAGE = "de.fau.cs.mad.yasme.android.SERVERMESSAGE";

    public final static String STORAGE_PREFS = "de.fau.cs.mad.yasme.android.STORAGE_PREFS";
    public final static String SETTINGS_PREFS = "de.fau.cs.mad.yasme.android.SETTINGS_PREFS";
    public final static String DEVICE_PREFS = "de.fau.cs.mad.yasme.android.DEVICE_PREFS";
    public final static String PUSH_PREFS = "de.fau.cs.mad.yasme.android.PUSH_PREFS";

    public final static String NOTIFICATION_VIBRATE = "de.fau.cs.mad.yasme.android.NOTIFICATION_VIBRATE";
    public final static String NOTIFICATION_SOUND = "de.fau.cs.mad.yasme.android.NOTIFICATION_SOUND";


    //GCM Properties
    public static final String PROPERTY_REG_ID = "registration_id";
    public static final String PROPERTY_APP_VERSION = "appVersion";
    public static final String SENDER_ID = "688782154540"; //"104759172131";
    public static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
    public static final String TAG = "YasmeGCM";

    protected User selfUser;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (!ConnectionTask.isInitialized()) {
            String server = getResources().getString(R.string.server_host);
            if (BuildConfig.DEBUG) {
                server = getResources().getString(R.string.server_host_debug);
            }
            Log.d(getClass().getSimpleName(), "YASME-Server: " + server);
            ConnectionTask.initParams(getResources().getString(R.string.server_scheme),
                    server,
                    getResources().getString(R.string.server_port), getResources().getString(R.string.language), getVersion());
        }

        SharedPreferences storage = getSharedPreferences(STORAGE_PREFS, MODE_PRIVATE);
        SharedPreferences settings = getSharedPreferences(SETTINGS_PREFS, MODE_PRIVATE);
        Long userId = storage.getLong(USER_ID, 0);
        String userName = storage.getString(USER_NAME, "");
        String userMail = storage.getString(USER_MAIL, "");
        String userPw = storage.getString(USER_PW, "password");

        if(selfUser==null) {
            selfUser = new User();
        }
        selfUser.setId(userId);
        selfUser.setName(userName);
        selfUser.setEmail(userMail);
        selfUser.setPw(userPw);


        //Initialize databaseManager (once in application)
        if (!DatabaseManager.INSTANCE.isInitialized()) {
            DatabaseManager.INSTANCE.init(this, storage, settings, userId);
        }
        //Init QR-Code
        QR.init(false);

        String accessToken = DatabaseManager.INSTANCE.getAccessToken();
        if ((accessToken == null || accessToken.length() <= 0) && !this.getClass().equals(LoginActivity.class)) {
            Log.i(this.getClass().getSimpleName(), "Not logged in, starting login activity");
            Intent intent = new Intent(this, LoginActivity.class);
            startActivity(intent);
            finish();
            return;
        }
    }

    @Override
    public void onStart() {
        super.onStart();
        Toaster.getInstance().register(this);
        stopSpinning();
        SpinnerObservable.getInstance().registerActivity(this);
    }

    @Override
    public void onResume() {
        super.onResume();
        String accessToken = DatabaseManager.INSTANCE.getAccessToken();
        if ((accessToken == null || accessToken.length() <= 0) && !this.getClass().equals(LoginActivity.class)) {
            Log.i(this.getClass().getSimpleName(), "Not logged in, starting login activity");
            Intent intent = new Intent(this, LoginActivity.class);
            startActivity(intent);
            finish();
            return;
        }
    }

    @Override
    public void onStop() {
        super.onStop();
        Toaster.getInstance().remove(this);
        SpinnerObservable.getInstance().removeActivity(this);
    }

    public void setActionBarTitle(String title) {
        getActionBar().setTitle(title);
    }

    public void setActionBarTitle(String title, String subtitle) {
        getActionBar().setTitle(title);
        getActionBar().setSubtitle(subtitle);
    }

    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        Intent intent;
        int itemId = item.getItemId();
        switch (itemId) {
            case android.R.id.home:
                if (NavUtils.getParentActivityName(this) != null) {
                    NavUtils.navigateUpFromSameTask(this);
                }
                return true;
            case R.id.action_settings:
                intent = new Intent(this, SettingsActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(intent);
                return true;
            case R.id.action_chats:
                intent = new Intent(this, ChatListActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(intent);
                return true;
            case R.id.action_add_chat:
                intent = new Intent(this, InviteToChatActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
                startActivity(intent);
                return true;
            case R.id.action_contacts:
                intent = new Intent(this, ContactActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
                startActivity(intent);
                return true;
            default:
                return super.onOptionsItemSelected(item);

        }
    }

    public String getSelfName() {

        if(selfUser==null) {
            SharedPreferences storage = getSharedPreferences(STORAGE_PREFS, MODE_PRIVATE);
            Long userId = storage.getLong(USER_ID, 0);
            String userName = storage.getString(USER_NAME, "");
            String userMail = storage.getString(USER_MAIL, "");
            String userPw = storage.getString(USER_PW, "password");

            selfUser = new User();
            selfUser.setId(userId);
            selfUser.setName(userName);
            selfUser.setEmail(userMail);
            selfUser.setPw(userPw);
        }
        if (selfUser.getName().isEmpty()) {
            String name = getSharedPreferences(STORAGE_PREFS, MODE_PRIVATE).getString(USER_NAME, "");
            selfUser.setName(name);
        }
        return selfUser.getName();
    }

    public User getSelfUser() {
        return selfUser;
    }

    public String getUserMail() {
        if (selfUser == null || selfUser.getEmail().isEmpty()) {
            String mail = getSharedPreferences(STORAGE_PREFS, MODE_PRIVATE).getString(USER_MAIL, "");
            selfUser.setEmail(mail);
        }
        return selfUser.getEmail();
    }

    public long getUserId() {
        return selfUser.getId();
    }

    public String getOwnProfilePicture() {
        String path = selfUser.getProfilePicture();
        if (path == null || path.isEmpty()) {
            path = getSharedPreferences(STORAGE_PREFS, MODE_PRIVATE).getString(PROFILE_PICTURE, null);
        }
        return path;
    }

    public void setOwnProfilePicture(String ownProfilePicture) {
        selfUser.setProfilePicture(ownProfilePicture);
        SharedPreferences.Editor editor = getSharedPreferences(STORAGE_PREFS, MODE_PRIVATE).edit();
        editor.putString(AbstractYasmeActivity.PROFILE_PICTURE, ownProfilePicture);
        editor.commit();
    }

    public String getAccessToken() {
        return DatabaseManager.INSTANCE.getAccessToken();
    }

    public void toast(final int messageId, final int duration) {
        String text = getApplicationContext().getResources().getString(messageId);
        toast(text, duration, -1);
    }

    public void toast(final String text, final int duration) {
        toast(text, duration, -1);
    }

    public void toast(final String text, final int duration, final int gravity) {
        runOnUiThread(new Runnable() {
            public void run() {
                Toast toast = Toast.makeText(getApplicationContext(), text, duration);
                if (-1 != gravity) {
                    toast.setGravity(gravity, 0, 0);
                }
                // otherwise use default position
                Log.d(getClass().getSimpleName(), "Toast: " + text);
                toast.show();
            }
        });
    }

    public void startSpinning() {
        runOnUiThread(new Runnable() {
            public void run() {
                setProgressBarIndeterminateVisibility(true);
            }
        });
    }

    public void stopSpinning() {
        runOnUiThread(new Runnable() {
            public void run() {
                setProgressBarIndeterminateVisibility(false);
            }
        });
    }

    public int getVersion() {
        try {
            return getPackageManager().getPackageInfo(getPackageName(), 0).versionCode;
        } catch (Exception e) {
            Log.e(this.getClass().getSimpleName(), e.getMessage());
            return 0;
        }
    }

}
yasme/src/main/java/de/fau/cs/mad/yasme/android/connection/UserTask.java
public class UserTask extends ConnectionTask {

    private static UserTask instance;

    public static synchronized UserTask getInstance() {
        if (instance == null) {
            synchronized (UserTask.class) {
                if (null == instance) {
                    instance = new UserTask();
                }
            }
        }
        return instance;
    }

    private UserTask() {
        try {
            this.uri = new URIBuilder(baseURI).setPath(ConnectionTask.APIVERSION + "/usr").build();
        } catch (URISyntaxException e) {
            Log.e(this.getClass().getSimpleName(), e.getMessage());
        }
    }

    public Long registerUser(User user) throws RestServiceException {

        try {
            HttpResponse httpResponse = executeRequest(Request.POST, "", user);
            JSONObject json = new JSONObject((new BufferedReader(
                    new InputStreamReader(httpResponse.getEntity()
                            .getContent(), "UTF-8")
            )).readLine());

            return Long.parseLong(json.getString("message"));
        } catch (IOException e) {
            throw new RestServiceException(Error.CONNECTION_ERROR);
        } catch (JSONException e) {
            throw new RestServiceException(Error.ERROR);
        }
    }

    public void changeUserData(User user) throws RestServiceException {
        executeRequest(Request.PUT, "", user);
        Log.d(this.getClass().getSimpleName(), "User name was: " + user.getName());
        Log.d(this.getClass().getSimpleName(), "User data changed");
    }


    public User getUser(long userId) throws RestServiceException {
        try {
            HttpResponse httpResponse = executeRequest(Request.GET, String.valueOf(userId));
            return new ObjectMapper().readValue(((new BufferedReader(new InputStreamReader(
                    httpResponse.getEntity().getContent(), "UTF-8"))).readLine()), User.class);
        } catch (IOException e) {
            throw new RestServiceException(Error.CONNECTION_ERROR);
        }
    }

    public User getUserData() throws RestServiceException {

        try {
            HttpResponse httpResponse = executeRequest(Request.GET, "");
            return new ObjectMapper().readValue(((new BufferedReader(new InputStreamReader(
                    httpResponse.getEntity().getContent(), "UTF-8"))).readLine()), User.class);
        } catch (IOException e) {
            throw new RestServiceException(Error.CONNECTION_ERROR);
        }
    }

    public void uploadProfilePicture(Bitmap bitmap) throws RestServiceException {

        HttpEntity multipartEntity = MultipartEntityBuilder.create()
                .addBinaryBody("file", PictureManager.INSTANCE.scaledBitmapToByteArray(bitmap, 500),
                        ContentType.create("image/jpeg"), "")
                .build();

        executeUpload(Request.POST, "profile", multipartEntity, null);
    }

    public BitmapDrawable getProfilePicture(long userId) throws RestServiceException {
        try {
            String path = "profile/" + userId;
            Map<String, String> headers = new HashMap<>();
            headers.put("Accept", "image/jpeg; q=0.5, image/png");
            HttpEntity response = (executeRequest(Request.GET, path, headers)).getEntity();
            if (null == response) {
                return null;
            }
            InputStream stream = response.getContent();
            Bitmap picture = BitmapFactory.decodeStream(stream);
            return new BitmapDrawable(DatabaseManager.INSTANCE.getContext().getResources(), picture);
        } catch (IOException e) {
            throw new RestServiceException(Error.CONNECTION_ERROR);
        }
    }

    public void requirePasswordToken(User user) throws RestServiceException {
        Log.d(getClass().getSimpleName(), "Require password token");
        HttpResponse httpResponse = executeRequest(Request.POST, "password/token/" + language, user);
    }

    public void changePassword(User user, String token) throws RestServiceException {
        Log.d(getClass().getSimpleName(), "Change password");
        HttpResponse httpResponse = executeRequest(Request.POST, "password/" + token, user);
    }
}
yasme/src/main/java/de/fau/cs/mad/yasme/android/exception/RestServiceException.java
public class RestServiceException extends Exception {

	private static final long serialVersionUID = 1L;
	private int code;

	public RestServiceException(ErrorCode error) {

		this(error.getDescription(), error.getNumber());

	}

	public RestServiceException(String message, int code) {
		super(message);
		this.code = code;

		System.err.println("Code: " + this.code + "  " + "Message: "
				+ this.getMessage());
	}

    public int getCode() {
        return code;
    }
}
yasme/src/main/java/de/fau/cs/mad/yasme/android/exception/Error.java
public enum Error implements ErrorCode {

    ERROR(000),

    GET_NO_NEW_MESSAGE(001),

    BAD_REQUEST(400),

    LOGIN_FAILED(401),

    UNAUTHORIZED(401),

    FORBIDDEN(403),

    NOT_FOUND_EXCEPTION(404),

    USER_NOT_FOUND(404),

    NOT_ACCEPTABLE(406),

    OUTDATED(409),

    INCOMPLETE_REQUEST(420),

    BAD_EMAIL(460),

    STORE_USER_FAILED(500),

    CONNECTION_ERROR(500),

    SEND_MESSAGE_FAILED(500),

    SERVER_ERROR(500),

    REGISTRATION_FAILED(500),

    STORE_FAILED_EXCEPTION(501);

    private final int number;

    private Error(int number) {
        this.number = number;
    }

    public int getNumber() {
        return number;
    }

    public String getDescription() {
        return name();
    }
}
yasme/src/main/java/de/fau/cs/mad/yasme/android/storage/DatabaseManager.java
public enum DatabaseManager {
    INSTANCE;

    private boolean mInitialized = false;
    private boolean mDBInitialized = false;
    private DatabaseHelper mHelper;
    private Context mContext;
    private long mUserId = -1;
    private long mDeviceId = -1;
    private String mAccessToken = null;
    private long serverInfoUpdateTime = -1;
    private ServerInfo serverInfo = null;
    private SharedPreferences mSharedPreferences, mSettings;
    private String mUserEmail;
    private NewMessageNotificationManager notifier = null;

    private UserDAO userDAO;
    private ChatDAO chatDAO;
    private MessageDAO messageDAO;
    private MessageKeyDAO messageKeyDAO;
    private DeviceDAO deviceDAO;


    public void init(Context context, SharedPreferences sharedPreferences,
                     SharedPreferences settings, long userId) {
        mContext = context;
        mSharedPreferences = sharedPreferences;
        mSettings = settings;
        mUserId = userId;
        initDB(context, userId);
        initializeDAOs();
        mInitialized = true;
    }

    public void initDB(Context context, long userId) {
        mHelper = new DatabaseHelper(context, userId);
        mDBInitialized = true;
    }

    public boolean isInitialized() {
        return mInitialized;
    }

    public boolean isDBInitialized() {
        return mDBInitialized;
    }

    private DatabaseHelper getHelper() {
        return mHelper;
    }

    public SharedPreferences getSharedPreferences() {
        return mSharedPreferences;
    }

    public SharedPreferences getSettings() {
        return mSettings;
    }

    public Context getContext() {
        return mContext;
    }

    private void initializeDAOs() {
        UserDAOImpl.INSTANCE.setDatabaseHelper(mHelper);
        userDAO = UserDAOImpl.INSTANCE;

        ChatDAOImpl.INSTANCE.setDatabaseHelper(mHelper);
        chatDAO = ChatDAOImpl.INSTANCE;

        MessageDAOImpl.INSTANCE.setDatabaseHelper(mHelper);
        messageDAO = MessageDAOImpl.INSTANCE;

        MessageKeyDAOImpl.INSTANCE.setDatabaseHelper(mHelper);
        messageKeyDAO = MessageKeyDAOImpl.INSTANCE;

        DeviceDAOImpl.INSTANCE.setDatabaseHelper(mHelper);
        deviceDAO = DeviceDAOImpl.INSTANCE;
    }

    public UserDAO getUserDAO() {
        return userDAO;
    }

    public ChatDAO getChatDAO() {
        return chatDAO;
    }

    public MessageDAO getMessageDAO() {
        return messageDAO;
    }

    public MessageKeyDAO getMessageKeyDAO() {
        return messageKeyDAO;
    }

    public DeviceDAO getDeviceDAO() {
        return deviceDAO;
    }

    public long getUserId() {
        if (-1 == mUserId) {
            mUserId = getSharedPreferences().getLong(AbstractYasmeActivity.USER_ID, -1);
        }
        return mUserId;
    }

    public void setUserId(long mUserId) {
        this.mUserId = mUserId;
        SharedPreferences.Editor editor = getSharedPreferences().edit();
        editor.putLong(AbstractYasmeActivity.USER_ID, mUserId);
        editor.apply();
    }

    public long getDeviceId() {
        if (-1 == mDeviceId) {
            mDeviceId = getSharedPreferences().getLong(AbstractYasmeActivity.DEVICE_ID, -1);
        }
        return mDeviceId;
    }

    public void setDeviceId(long mDeviceId) {
        this.mDeviceId = mDeviceId;
        SharedPreferences.Editor editor = getSharedPreferences().edit();
        editor.putLong(AbstractYasmeActivity.DEVICE_ID, mDeviceId);
        editor.apply();
    }

    public String getAccessToken() {
        if (null == mAccessToken) {
            mAccessToken = getSharedPreferences().getString(AbstractYasmeActivity.ACCESSTOKEN, null);
        }
        return mAccessToken;
    }

    public void setAccessToken(String accessToken) {
        this.mAccessToken = accessToken;
        SharedPreferences.Editor editor = getSharedPreferences().edit();
        editor.putString(AbstractYasmeActivity.ACCESSTOKEN, mAccessToken);
        editor.commit();
    }

    public long getServerInfoUpdateTime() {
        if (-1 == serverInfoUpdateTime) {
            serverInfoUpdateTime = getSharedPreferences().getLong(AbstractYasmeActivity.SERVERINFOUPDATETIME, -1);
        }
        return serverInfoUpdateTime;
    }

    public void setServerInfoUpdateTime() {
        this.serverInfoUpdateTime = System.currentTimeMillis();
        SharedPreferences.Editor editor = getSharedPreferences().edit();
        editor.putLong(AbstractYasmeActivity.SERVERINFOUPDATETIME, serverInfoUpdateTime);
        editor.commit();
    }

    public ServerInfo getServerInfo() {
        return serverInfo;
    }

    public void setServerInfo(ServerInfo serverInfo) {
        this.serverInfo = serverInfo;
    }

    public String getUserEmail() {
        if (null == mUserEmail || "" == mUserEmail) {
            mUserEmail = getSharedPreferences().getString(AbstractYasmeActivity.USER_MAIL, null);
        }
        return mUserEmail;
    }

    public void setUserEmail(String mUserEmail) {
        this.mUserEmail = mUserEmail;
        SharedPreferences.Editor editor = getSharedPreferences().edit();
        editor.putString(AbstractYasmeActivity.USER_MAIL, mUserEmail);
        editor.commit();
    }

    public NewMessageNotificationManager getNotifier() {
        if (notifier == null) {
            notifier = new NewMessageNotificationManager();
        }
        return notifier;
    }
}
yasme/src/main/java/de/fau/cs/mad/yasme/android/controller/ObservableRegistry.java
public class ObservableRegistry {

    private static ArrayList<ObservableRegistryEntry> entries = new ArrayList<ObservableRegistryEntry>();

    public static <T extends NotifiableFragment<P>, P> FragmentObservable<T, P> getObservable(Class fragmentClass) {
        for (ObservableRegistryEntry entry : entries) {
            if (entry.check(fragmentClass)) {
                Log.d("ObserverRegistry","Returned existing observable");
                return (FragmentObservable<T,P>) entry.getObs(); // no idea how to solve this... 
            }
        }

        FragmentObservable<T, P> res = new FragmentObservable<T, P>();
        Log.d("ObserverRegistry","Created new observable");
        entries.add(new ObservableRegistryEntry<P>(res,fragmentClass));
        return res;
    }
}
yasme/src/main/java/de/fau/cs/mad/yasme/android/controller/SpinnerObservable.java
public class SpinnerObservable {
    private Set<AsyncTask> backgroundTasks;
    private Set<AbstractYasmeActivity> activities;
    private boolean spinning = false;

    private static SpinnerObservable instance;

    public static SpinnerObservable getInstance() {
        if (instance == null) {
            instance = new SpinnerObservable();
        }
        return instance;
    }

    private SpinnerObservable() {
        backgroundTasks = new HashSet<>();
        activities = new HashSet<>();
    }

    public void registerActivity(AbstractYasmeActivity activity) {
        Log.d(getClass().getSimpleName(), "Register activity");
        activities.add(activity);
        if (spinning) {
            Log.d(getClass().getSimpleName(), "Start spinning");
            activity.startSpinning();
        } else {
            Log.d(getClass().getSimpleName(), "No spinning");
        }
    }

    public void removeActivity(AbstractYasmeActivity activity) {
        Log.d(getClass().getSimpleName(), "Remove activity");
        activities.remove(activity);
    }

    public void registerBackgroundTask(AsyncTask backgroundTask) {
        Log.d(getClass().getSimpleName(), "Register backgroundTask: " + backgroundTask.getClass().getSimpleName());
        backgroundTasks.add(backgroundTask);
        spinning = true;
        startSpinning();
    }

    public void removeBackgroundTask(AsyncTask backgroundTask) {
        Log.d(getClass().getSimpleName(), "Remove backgroundTask: " + backgroundTask.getClass().getSimpleName());
        backgroundTasks.remove(backgroundTask);
        if (backgroundTasks.size() == 0) {
            spinning = false;
            stopSpinning();
        }
    }

    public void startSpinning() {
        Log.d(getClass().getSimpleName(), "Start spinning");
        for (AbstractYasmeActivity activity : activities) {
            activity.startSpinning();
        }
    }

    public void stopSpinning() {
        Log.d(getClass().getSimpleName(), "Stop spinning");
        for (AbstractYasmeActivity activity : activities) {
            activity.stopSpinning();
        }
    }
}
yasme/src/main/java/de/fau/cs/mad/yasme/android/encryption/PasswordEncryption.java
public class PasswordEncryption{

    private static final String SALT = "Y45M3";
    private User user;

    public PasswordEncryption(User user) {
        this.user = user;
    }

    /**
     * get a secure password (hashed and salted)
     *
     * @return user-object containing the secure password
     */
    public User securePassword(){
        String secure = getSecurePassword();
        user.setPw(secure);
        return user;
    }


    /**
     * get a secure password (hashed and salted)
     *
     * @return hashed and salted password as String
     */
    public String getSecurePassword(){
        return SHA512(salt(SALT,user.getPw()));
    }


    /**
     * hash the password using SHA-512
     *
     * @param password password that should be hashed
     * @return hashed String
     */
    private String SHA512(String password){
       try {
           MessageDigest md = MessageDigest.getInstance("SHA-512");
           md.update(password.getBytes("UTF-8"));
           byte[] hash = md.digest();
           Base64 base64 = new Base64();
           return new String(base64.base64Encode(hash));
       }
       catch (Exception e){
           Log.d(this.getClass().getSimpleName(), "Hashing Password failed");
           Log.d(this.getClass().getSimpleName(), "Error: " + e.getMessage());
       }
       return null;
    }

    /**
     * salt the password
     *
     * @param salt salt-value that should be used
     * @param password password that should be secured
     * @return salted password
     */
    private String salt(String salt, String password){
        String passwordSalted = salt+password;
        return passwordSalted;
    }
}
yasme/src/main/java/de/fau/cs/mad/yasme/android/entities/User.java
@JsonIgnoreProperties(ignoreUnknown = true)
@DatabaseTable(tableName = DatabaseConstants.USER_TABLE)
public class User implements Serializable {

    @DatabaseField(columnName = DatabaseConstants.USER_ID, id = true)
    private long id;

    @DatabaseField(columnName = DatabaseConstants.USER_NAME)
    private String name;

    //@DatabaseField(columnName = DatabaseConstants.USER_EMAIL)
    private String email;

    private String pw;

    @JsonIgnore
    private List<Device> devices;   // Just for convenience

    @DatabaseField(columnName = DatabaseConstants.USER_LAST_MODIFIED)
    private Date lastModified;

    @DatabaseField(columnName = DatabaseConstants.USER_CREATED)
    private Date created;

    @JsonIgnore
    @DatabaseField(columnName = DatabaseConstants.USER_PICTURE)
    private String profilePicture;


    @JsonIgnore
    @DatabaseField(columnName = DatabaseConstants.CONTACT)
    private int contactFlag = 0;


    public User(String pw, String name, String email) {
        this.pw = pw;
        this.name = name;
        this.email = email;
    }

    public User(String email, String pw) {
        this.email = email;
        this.pw = pw;
    }

    public User(String name, long id) {
        this.name = name;
        this.id = id;
    }

    public User(long id) {
        this.id = id;
    }

    public User(String name, String email, long id) {
        this.name = name;
        this.email = email;
        this.id = id;
    }

    public User() {
        // ORMLite needs a no-arg constructor
    }

    /*
     * Getters
     */

    @JsonIgnoreProperties({"id", "user", "publicKey", "product", "lastModified"})
    public List<Device> getDevices() {
        return devices;
    }

    public String getEmail() {
        return email;
    }

    public String getName() {
        return name;
    }

    public String getPw() {
        return pw;
    }

    public long getId() {
        return id;
    }

    public Date getLastModified() {
        return lastModified;
    }

    public Date getCreated() {
        return created;
    }

    public String getProfilePicture() {
        return profilePicture;
    }

    /*
     * Setters
     */

    public void setDevices(List<Device> devices) {
        this.devices = devices;
    }

    public void setPw(String pw) {
        this.pw = pw;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setId(long id) {
        this.id = id;
    }

    public void setLastModified(Date lastModified) {
        this.lastModified = lastModified;
    }

    public void setCreated(Date created) {
        this.created = created;
    }

    public void setProfilePicture(String profilePicture) {
        this.profilePicture = profilePicture;
    }

    @JsonIgnore
    public void addToContacts() {
        contactFlag = 1;
    }

    @JsonIgnore
    public void removeFromContacts() {
        contactFlag = 0;
    }

    @JsonIgnore
    public boolean isContact() {
        return contactFlag == 1;
    }

}
yasme/src/main/java/de/fau/cs/mad/yasme/android/ui/fragments/RegisterFragment.java
public class RegisterFragment extends Fragment implements NotifiableFragment<RegisterFragment.RegistrationParam> {

    public static String inputName = "";
    public static String inputMail = "";
    public static String inputPass1 = "";
    public static String inputPass2 = "";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        registerDialog(true);
    }

    private void registerDialog(final boolean acceptedTos) {
        AbstractYasmeActivity activity = (AbstractYasmeActivity) getActivity();
        AlertDialog.Builder alert = new AlertDialog.Builder(activity);
        alert.setTitle(getString(R.string.registration_title));

        LinearLayout list = new LinearLayout(activity);
        list.setOrientation(LinearLayout.VERTICAL);
        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.MATCH_PARENT);
        final EditText name = new EditText(activity);
        name.setHint(R.string.registration_name);
        name.setText(inputName);

        final EditText mail = new EditText(activity);
        mail.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
        mail.setHint(R.string.registration_email);
        mail.setText(inputMail);

        final EditText password = new EditText(activity);
        password.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
        password.setHint(R.string.registration_password);
        password.setText(inputPass1);

        final EditText passwordCheck = new EditText(activity);
        passwordCheck.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
        passwordCheck.setHint(R.string.registration_repeat_password);
        passwordCheck.setText(inputPass2);

        String checkBoxText = getString(R.string.read_TOS_start) + " " +
                getString(R.string.TOS) + " " +
                getString(R.string.read_TOS_middle) + " " +
                getString(R.string.privacy_policy) + " " +
                getString(R.string.read_TOS_end);

        final CheckBox checkBox = new CheckBox(activity);
        checkBox.setText(checkBoxText);

        Pattern pattern = Pattern.compile(getString(R.string.TOS));
        Linkify.addLinks(checkBox, pattern, "", null, new Linkify.TransformFilter() {
            @Override
            public String transformUrl(Matcher matcher, String s) {
                return getString(R.string.TOS_url);
            }
        });
        pattern = Pattern.compile(getString(R.string.privacy_policy));
        Linkify.addLinks(checkBox, pattern, "", null, new Linkify.TransformFilter() {
            @Override
            public String transformUrl(Matcher matcher, String s) {
                return getString(R.string.privacy_policy_url);
            }
        });

        if (!acceptedTos) {
            checkBox.setError(getString(R.string.no_TOS_toast) + " " +
                    getString(R.string.TOS) + " " +
                    getString(R.string.read_TOS_middle) + " " +
                    getString(R.string.privacy_policy));
        }

        list.addView(name, layoutParams);
        list.addView(mail, layoutParams);
        list.addView(password, layoutParams);
        list.addView(passwordCheck, layoutParams);
        list.addView(checkBox, layoutParams);

        alert.setView(list);

        // "OK" button to save the values
        alert.setPositiveButton(R.string.registration_button_ok,
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {

                        // Grab the EditText's input
                        String inputName = name.getText().toString();
                        String inputMail = mail.getText().toString();
                        String inputPassword = password.getText().toString();
                        String inputPasswordCheck = passwordCheck.getText()
                                .toString();

                        RegisterFragment.inputName = inputName;
                        RegisterFragment.inputMail = inputMail;
                        RegisterFragment.inputPass1 = inputPassword;
                        RegisterFragment.inputPass2 = inputPasswordCheck;

                        if (password.getText().length() < 8) {
                            Toaster.getInstance().toast(R.string.password_too_short, Toast.LENGTH_LONG);
                            return;
                        }
                        if (inputName.length() < 1) {
                            Toaster.getInstance().toast(R.string.name_too_short, Toast.LENGTH_LONG);
                            return;
                        }
                        if (!inputPassword.equals(inputPasswordCheck)) {
                            Toaster.getInstance().toast(R.string.passwords_do_not_match, Toast.LENGTH_LONG);
                            return;
                        }

                        if (checkBox.isChecked()) {
                            AbstractYasmeActivity activity = (AbstractYasmeActivity) getActivity();
                            IBinder ib = null;
                            InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
                            if (null != checkBox) ib = checkBox.getWindowToken();
                            if (null != imm && null != ib) imm.hideSoftInputFromWindow(ib, 0);
                            new UserRegistrationTask(RegisterFragment.class)
                                    .execute(inputName, inputMail, inputPassword, inputPasswordCheck,
                                            this.getClass().getName());
                        } else {
                            Toaster.getInstance().toast(
                                    getString(R.string.no_TOS_toast) + " " +
                                            getString(R.string.TOS) + " " +
                                            getString(R.string.read_TOS_middle) + " " +
                                            getString(R.string.privacy_policy), Toast.LENGTH_LONG);
                            registerDialog(false);
                        }
                    }
                }
        );

        // "Cancel" button
        alert.setNegativeButton(R.string.registration_button_cancel,
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                        dialog.cancel();
                    }
                }
        );
        alert.show();
    }

    public void onPostRegisterExecute(Boolean success, String email, String password, int message) {

        if (success) {
            //Login after registration was successfull
            Toaster.getInstance().toast(getResources().getString(
                    message), Toast.LENGTH_SHORT);
            UserLoginTask authTask = new UserLoginTask(false, LoginFragment.class);
            authTask.execute(email, password, this.getClass().getName());
            ((AbstractYasmeActivity) getActivity()).getSelfUser().setEmail(email);
        } else {
            Toaster.getInstance().toast(getResources().getString(message), Toast.LENGTH_LONG);
        }
    }

    @Override
    public void onStart() {
        super.onStart();
        Log.d(this.getClass().getSimpleName(), "Try to get LoginObservableInstance");
        FragmentObservable<RegisterFragment, RegistrationParam> obs =
                ObservableRegistry.getObservable(RegisterFragment.class);
        Log.d(this.getClass().getSimpleName(), "... successful");

        obs.register(this);
    }

    @Override
    public void onStop() {
        super.onStop();
        FragmentObservable<RegisterFragment, RegistrationParam> obs =
                ObservableRegistry.getObservable(RegisterFragment.class);
        Log.d(this.getClass().getSimpleName(), "Remove from observer");
        obs.remove(this);
    }

    @Override
    public void notifyFragment(RegistrationParam regParam) {
        Log.d(super.getClass().getSimpleName(), "I have been notified. Yeeha!");
        onPostRegisterExecute(regParam.getSuccess(), regParam.getEmail(), regParam.getPassword(), regParam.getMessage());
    }


    public static class RegistrationParam {
        protected Boolean success;
        private String email;
        private String password;
        private int message;

        public RegistrationParam(boolean success, String email, String password, int message) {
            this.success = success;
            this.email = email;
            this.password = password;
            this.message = message;
        }

        public Boolean getSuccess() {
            return success;
        }

        public String getEmail() {
            return email;
        }

        public String getPassword() {
            return password;
        }

        public int getMessage() {
            return message;
        }
    }
}
yasme/src/main/java/de/fau/cs/mad/yasme/android/controller/Log.java
public class Log {
    static final boolean LOG_I = BuildConfig.DEBUG;
    static final boolean LOG_E = BuildConfig.DEBUG;
    static final boolean LOG_D = BuildConfig.DEBUG;
    static final boolean LOG_V = BuildConfig.DEBUG;
    static final boolean LOG_W = BuildConfig.DEBUG;

    public static void i(String tag, String string) {
        if (LOG_I) android.util.Log.i(tag, string);
    }
    public static void e(String tag, String string) {
        if (LOG_E) android.util.Log.e(tag, string);
    }
    public static void d(String tag, String string) {
        if (LOG_D) android.util.Log.d(tag, string);
    }
    public static void v(String tag, String string) {
        if (LOG_V) android.util.Log.v(tag, string);
    }
    public static void w(String tag, String string) {
        if (LOG_W) android.util.Log.w(tag, string);
    }
}


Question: package de.fau.cs.mad.yasme.android.asyncTasks.server;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import de.fau.cs.mad.yasme.android.R;
import de.fau.cs.mad.yasme.android.connection.UserTask;
import de.fau.cs.mad.yasme.android.controller.Log;
import de.fau.cs.mad.yasme.android.controller.ObservableRegistry;
import de.fau.cs.mad.yasme.android.controller.SpinnerObservable;
import de.fau.cs.mad.yasme.android.encryption.PasswordEncryption;
import de.fau.cs.mad.yasme.android.entities.User;
import de.fau.cs.mad.yasme.android.exception.Error;
import de.fau.cs.mad.yasme.android.exception.RestServiceException;
import de.fau.cs.mad.yasme.android.storage.DatabaseManager;
import de.fau.cs.mad.yasme.android.ui.AbstractYasmeActivity;
import de.fau.cs.mad.yasme.android.ui.fragments.RegisterFragment;



/**
 * Created by Robert Meissner <robert.meissner@studium.fau.de> on 19.06.14.
 */

/**
 * Represents an asynchronous task used to register the user.
 */
public class UserRegistrationTask extends AsyncTask<String, Void, Boolean> {

    private String name;
    private String email;
    private String password;
    private Class classToNotify;
    private long userId;
    private int message = R.string.registration_successful;

    public UserRegistrationTask(Class classToNotify) {
        this.classToNotify = classToNotify;
    }


    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        SpinnerObservable.getInstance().registerBackgroundTask(this);
    }

    /**
     * @params params[0] is name
     * @params params[1] is email
     * @params params[2] is password
     * @params params[3] is password_check
     */
    @Override
    protected Boolean doInBackground(String... params) {
        name = params[0];
        email = params[1].toLowerCase();
        password = params[2];
        String password_check = params[3];

        if (!password.equals(password_check)) {
            return false;
        }
        try {
            PasswordEncryption pwEnc = new PasswordEncryption(new User(email, password));
            password = pwEnc.getSecurePassword();
            userId = UserTask.getInstance().registerUser(new User(password, name, email));
        } catch (RestServiceException e) {
            message = R.string.registration_not_successful;
            if (e.getCode() == Error.BAD_EMAIL.getNumber()) {
                message = R.string.email_invalid;
            }
            if (e.getCode() == Error.FORBIDDEN.getNumber()) {
                message = R.string.email_exists;
            }
            Log.e(this.getClass().getSimpleName(), e.getMessage());
            return false;
        }
        return true;
    }

    @Override
    protected void onPostExecute(final Boolean success) {
        SpinnerObservable.getInstance().removeBackgroundTask(this);
        // Ask server for news, i.e. new version of app
        new GetInfoTask().execute();

        if (success) {
            SharedPreferences.Editor editor = DatabaseManager.INSTANCE.getSharedPreferences().edit();
            editor.putString(AbstractYasmeActivity.USER_NAME, name);
            editor.putLong(AbstractYasmeActivity.LAST_MESSAGE_ID, 0L);
            editor.putLong(AbstractYasmeActivity.USER_ID, userId);
            editor.commit();
        }
        ObservableRegistry.getObservable(classToNotify).notifyFragments(
Answer:                 new RegisterFragment.RegistrationParam(success, email, password, message));