// Path: app/src/main/java/info/izumin/android/sunazuri/domain/entity/AuthorizedUser.java
// public class AuthorizedUser {
//     public static final String TAG = AuthorizedUser.class.getSimpleName();
// 
//     public final long id;
//     public final String name;
//     public final String screenName;
//     public final Date createdAt;
//     public final Date updatedAt;
//     public final String icon;
//     public final String email;
// 
//     public final AccessToken token;
// 
//     public AuthorizedUser(long id,
//                           String name,
//                           String screenName,
//                           Date createdAt,
//                           Date updatedAt,
//                           String icon,
//                           String email,
//                           AccessToken token) {
//         this.id = id;
//         this.name = name;
//         this.screenName = screenName;
//         this.createdAt = createdAt;
//         this.updatedAt = updatedAt;
//         this.icon = icon;
//         this.email = email;
//         this.token = token;
//     }
// }
// 
// Path: app/src/main/java/info/izumin/android/sunazuri/domain/entity/LoginInfo.java
// public class LoginInfo {
//     public static final String TAG = LoginInfo.class.getSimpleName();
// 
//     public final AuthorizedUser user;
//     public final Team team;
// 
//     public LoginInfo(AuthorizedUser user, Team team) {
//         this.user = user;
//         this.team = team;
//     }
// }
// 
// Path: app/src/main/java/info/izumin/android/sunazuri/domain/repository/UsersRepository.java
// public interface UsersRepository {
//     Observable<AuthorizedUser> getCurrentUser();
//     Single<List<AuthorizedUser>> getAuthorizedUsers();
//     Observable<LoginInfo> getLoginInfo();
// }
// 
// Path: app/src/main/java/info/izumin/android/sunazuri/infrastructure/repository/source/oauth/OauthDataSourceFactory.java
// public interface OauthDataSourceFactory {
//     OauthDataSource createLocalDataSource();
//     OauthDataSource createRemoteDataSource();
// }
// 
// Path: app/src/main/java/info/izumin/android/sunazuri/infrastructure/repository/source/team/TeamsDataSourceFactory.java
// public interface TeamsDataSourceFactory {
//     TeamsDataSource createLocalDataSource();
//     TeamsDataSource createRemoteDataSource();
// }


import info.izumin.android.sunazuri.domain.entity.AuthorizedUser;
import info.izumin.android.sunazuri.domain.entity.LoginInfo;
import info.izumin.android.sunazuri.domain.repository.UsersRepository;
import info.izumin.android.sunazuri.infrastructure.entity.mapper.AuthorizedUserMapper;
import info.izumin.android.sunazuri.infrastructure.entity.mapper.TeamMapper;
import info.izumin.android.sunazuri.infrastructure.repository.source.oauth.OauthDataSourceFactory;
import info.izumin.android.sunazuri.infrastructure.repository.source.team.TeamsDataSourceFactory;
import rx.Observable;
import rx.Single;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.List;
        this.teamMapper = teamMapper;
    }

    @Override
    public Observable<AuthorizedUser> getCurrentUser() {
        return oauthDataSourceFactory.createLocalDataSource()
                .getCurrentToken()
                .map(authorizedUserMapper::transform);
    }

    @Override
    public Single<List<AuthorizedUser>> getAuthorizedUsers() {
        return oauthDataSourceFactory.createLocalDataSource()
                .getTokens()
                .map(authorizedUserMapper::transform);
    }

    @Override
    public Observable<LoginInfo> getLoginInfo() {
        return Observable.zip(
                oauthDataSourceFactory.createLocalDataSource()
                        .getCurrentToken()
                        .defaultIfEmpty(null)
                        .map(authorizedUserMapper::transform),
                teamsDataSourceFactory.createLocalDataSource()
                        .getCurrentTeam()
                        .defaultIfEmpty(null)
                        .map(teamMapper::transform),
                (user, team) -> {
                    if (user != null && team != null) {
// Path: app/src/main/java/info/izumin/android/sunazuri/domain/entity/AuthorizedUser.java
// public class AuthorizedUser {
//     public static final String TAG = AuthorizedUser.class.getSimpleName();
// 
//     public final long id;
//     public final String name;
//     public final String screenName;
//     public final Date createdAt;
//     public final Date updatedAt;
//     public final String icon;
//     public final String email;
// 
//     public final AccessToken token;
// 
//     public AuthorizedUser(long id,
//                           String name,
//                           String screenName,
//                           Date createdAt,
//                           Date updatedAt,
//                           String icon,
//                           String email,
//                           AccessToken token) {
//         this.id = id;
//         this.name = name;
//         this.screenName = screenName;
//         this.createdAt = createdAt;
//         this.updatedAt = updatedAt;
//         this.icon = icon;
//         this.email = email;
//         this.token = token;
//     }
// }
// 
// Path: app/src/main/java/info/izumin/android/sunazuri/domain/entity/LoginInfo.java
// public class LoginInfo {
//     public static final String TAG = LoginInfo.class.getSimpleName();
// 
//     public final AuthorizedUser user;
//     public final Team team;
// 
//     public LoginInfo(AuthorizedUser user, Team team) {
//         this.user = user;
//         this.team = team;
//     }
// }
// 
// Path: app/src/main/java/info/izumin/android/sunazuri/domain/repository/UsersRepository.java
// public interface UsersRepository {
//     Observable<AuthorizedUser> getCurrentUser();
//     Single<List<AuthorizedUser>> getAuthorizedUsers();
//     Observable<LoginInfo> getLoginInfo();
// }
// 
// Path: app/src/main/java/info/izumin/android/sunazuri/infrastructure/repository/source/oauth/OauthDataSourceFactory.java
// public interface OauthDataSourceFactory {
//     OauthDataSource createLocalDataSource();
//     OauthDataSource createRemoteDataSource();
// }
// 
// Path: app/src/main/java/info/izumin/android/sunazuri/infrastructure/repository/source/team/TeamsDataSourceFactory.java
// public interface TeamsDataSourceFactory {
//     TeamsDataSource createLocalDataSource();
//     TeamsDataSource createRemoteDataSource();
// }


// Path: app/src/main/java/info/izumin/android/sunazuri/infrastructure/repository/UsersRepositoryImpl.java
import info.izumin.android.sunazuri.domain.entity.AuthorizedUser;
import info.izumin.android.sunazuri.domain.entity.LoginInfo;
import info.izumin.android.sunazuri.domain.repository.UsersRepository;
import info.izumin.android.sunazuri.infrastructure.entity.mapper.AuthorizedUserMapper;
import info.izumin.android.sunazuri.infrastructure.entity.mapper.TeamMapper;
import info.izumin.android.sunazuri.infrastructure.repository.source.oauth.OauthDataSourceFactory;
import info.izumin.android.sunazuri.infrastructure.repository.source.team.TeamsDataSourceFactory;
import rx.Observable;
import rx.Single;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.List;

        this.teamMapper = teamMapper;
    }

    @Override
    public Observable<AuthorizedUser> getCurrentUser() {
        return oauthDataSourceFactory.createLocalDataSource()
                .getCurrentToken()
                .map(authorizedUserMapper::transform);
    }

    @Override
    public Single<List<AuthorizedUser>> getAuthorizedUsers() {
        return oauthDataSourceFactory.createLocalDataSource()
                .getTokens()
                .map(authorizedUserMapper::transform);
    }

    @Override
    public Observable<LoginInfo> getLoginInfo() {
        return Observable.zip(
                oauthDataSourceFactory.createLocalDataSource()
                        .getCurrentToken()
                        .defaultIfEmpty(null)
                        .map(authorizedUserMapper::transform),
                teamsDataSourceFactory.createLocalDataSource()
                        .getCurrentTeam()
                        .defaultIfEmpty(null)
                        .map(teamMapper::transform),
                (user, team) -> {
                    if (user != null && team != null) {
                        return new LoginInfo(user, team);