/*
 * Copyright 2012 GitHub Inc.
 *
 * 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.github.mobile.accounts;

import static com.github.mobile.accounts.AccountUtils.getAccount;
import static com.google.common.base.Preconditions.checkState;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.Activity;
import android.util.Log;

import com.google.common.base.Function;
import com.google.common.collect.MapMaker;
import com.google.inject.AbstractModule;
import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.OutOfScopeException;

import java.util.Map;
import java.util.concurrent.ConcurrentMap;


/**
 * Custom Guice-scope that makes an authenticated GitHub account available,
 * by enforcing that the user is logged in before proceeding.
 */
public class AccountScope extends ScopeBase {

    private final static String TAG = "GitHubAccountScope";

    private final static Key<GitHubAccount> GITHUB_ACCOUNT_KEY = Key.get(GitHubAccount.class);

    public static Module module() {
        return new AbstractModule() {
            public void configure() {
                AccountScope scope = new AccountScope();

                bind(AccountScope.class).toInstance(scope);

                bind(GITHUB_ACCOUNT_KEY).toProvider(AccountScope.<GitHubAccount>seededKeyProvider()).in(scope);
            }
        };
    }

    private final ThreadLocal<GitHubAccount> currentAccount = new ThreadLocal<GitHubAccount>();

    private final Map<GitHubAccount, Map<Key<?>, Object>> repoScopeMaps = new MapMaker().
        makeComputingMap(new Function<GitHubAccount, Map<Key<?>, Object>>() {
            public Map<Key<?>, Object> apply(GitHubAccount account) {
                ConcurrentMap<Key<?>, Object> accountScopeMap = new MapMaker().makeMap();
                accountScopeMap.put(GITHUB_ACCOUNT_KEY, account);
                return accountScopeMap;
            }
        });

    /**
     * Enters scope once we've ensured the user has a valid account.
     */
    public void enterWith(Activity activityUsedToStartLoginProcess) {
        AccountManager accountManager = AccountManager.get(activityUsedToStartLoginProcess);
        Account account = getAccount(accountManager, activityUsedToStartLoginProcess);
        enterWith(account, accountManager);
    }

    /**
     * Enters scope using a GitHubAccount derived from the supplied account
     */
    public void enterWith(Account account, AccountManager accountManager) {
        enterWith(new GitHubAccount(account.name, accountManager.getPassword(account)));
    }

    public void enterWith(GitHubAccount account) {
        Log.d(TAG, "entering scope with " + account);
        checkState(currentAccount.get() == null, "A scoping block is already in progress");
        currentAccount.set(account);
    }

    public void exit() {
        Log.d(TAG, "exiting scope");
        checkState(currentAccount.get() != null, "No scoping block in progress");
        currentAccount.remove();
    }

    @Override
    protected <T> Map<Key<?>, Object> getScopedObjectMap(Key<T> key) {
        GitHubAccount account = currentAccount.get();
        if (account == null) {
            throw new OutOfScopeException("Cannot access " + key + " outside of a scoping block");
        }
        return repoScopeMaps.get(account);
    }


}
@@ -1179,17 +1179,16 @@
 ntMap;%0A%0A
-%0A
 /**%0A * C
@@ -1258,19 +1258,16 @@
 ailable,
-%0A *
  by enfo
@@ -1298,16 +1298,19 @@
 ogged in
+%0A *
  before 
@@ -1840,16 +1840,17 @@
 Account%3E
+ 
 seededKe
@@ -2090,17 +2090,16 @@
 pMaker()
-.
 %0A       
@@ -2099,16 +2099,21 @@
         
+    .
 makeComp
@@ -2182,24 +2182,28 @@
             
+  
+  
 public Map%3CK
@@ -2240,32 +2240,36 @@
 ount account) %7B%0A
+    
                 
@@ -2358,16 +2358,20 @@
         
+ 
+   
 accountS
@@ -2424,24 +2424,28 @@
             
+    
 return accou
@@ -2460,34 +2460,42 @@
 ap;%0A            
-%7D%0A
+    %7D%0A    
         %7D);%0A%0A   
@@ -3894,11 +3894,9 @@
 ;%0A    %7D%0A
-%0A%0A
 %7D

Remove extra newlines