// Path: src/main/java/org/lbogdanov/poker/core/User.java
// @Entity
// @Table(name = "USERS")
// public class User extends AbstractEntity {
// 
//     @Column(name = "FIRST_NAME", length = USER_FIRST_NAME_MAX_LENGTH, nullable = false)
//     private String firstName = "";
//     @Column(name = "LAST_NAME", length = USER_LAST_NAME_MAX_LENGTH, nullable = true)
//     private String lastName = "";
//     @Column(name = "EMAIL", length = USER_EMAIL_MAX_LENGTH, nullable = true)
//     private String email = "";
//     @Column(name = "EXTERNAL_ID", length = USER_EXTERNAL_ID_MAX_LENGTH, nullable = false, unique = true)
//     private String externalId = "";
// 
//     /**
//      * Returns a user's first name.
//      * 
//      * @return the firstName
//      */
//     public String getFirstName() {
//         return firstName;
//     }
// 
//     /**
//      * Sets a user's first name, only the first {@link Constants.USER_FIRST_NAME_MAX_LENGTH} characters are stored.
//      * 
//      * @param firstName the first name to set
//      */
//     public void setFirstName(String firstName) {
//         this.firstName = limitString(firstName, USER_FIRST_NAME_MAX_LENGTH);
//     }
// 
//     /**
//      * Returns a user's last name.
//      * 
//      * @return the last name
//      */
//     public String getLastName() {
//         return lastName;
//     }
// 
//     /**
//      * Sets a user's last name, only the first {@link Constants.USER_LAST_NAME_MAX_LENGTH} characters are stored.
//      * 
//      * @param lastName the last name to set
//      */
//     public void setLastName(String lastName) {
//         this.lastName = limitString(lastName, USER_LAST_NAME_MAX_LENGTH);
//     }
// 
//     /**
//      * Returns a user's e-mail.
//      * 
//      * @return the e-mail
//      */
//     public String getEmail() {
//         return email;
//     }
// 
//     /**
//      * Sets a user's e-mail, only the first {@link Constants.USER_EMAIL_MAX_LENGTH} characters are stored.
//      * 
//      * @param email the e-mail to set
//      */
//     public void setEmail(String email) {
//         this.email = limitString(email, USER_EMAIL_MAX_LENGTH);
//     }
// 
//     /**
//      *  Returns a user's ID in an external system from which the user originates.
//      * 
//      * @return the external ID
//      */
//     public String getExternalId() {
//         return externalId;
//     }
// 
//     /**
//      * Sets a user's ID in an external system, only the first {@link Constants.USER_EXTERNAL_ID_MAX_LENGTH} characters are stored.
//      * 
//      * @param externalId the external ID
//      */
//     public void setExternalId(String externalId) {
//         this.externalId = limitString(externalId, USER_EXTERNAL_ID_MAX_LENGTH);
//     }
// 
//     /**
//      * {@inheritDoc}
//      */
//     @Override
//     public int hashCode() {
//         return Objects.hashCode(getExternalId());
//     }
// 
//     /**
//      * {@inheritDoc}
//      */
//     @Override
//     public boolean equals(Object obj) {
//         if (this == obj) {
//             return true;
//         }
//         if (obj instanceof User) {
//             User other = (User) obj;
//             return Objects.equal(this.getExternalId(), other.getExternalId());
//         }
//         return false;
//     }
// 
// }
// 
// Path: src/main/java/org/lbogdanov/poker/core/UserService.java
// public interface UserService {
// 
//     /**
//      * Returns currently logged in <code>User</code> instance.
//      * 
//      * @return the <code>User</code> object or <code>null</code> for an anonymous user
//      */
//     public User getCurrentUser();
// 
//     /**
//      * Performs a login attempt with specified credentials.
//      * 
//      * @param username the user name
//      * @param password the password
//      * @param rememberme  if a user identity should be remembered across sessions
//      * @throws <code>RuntimeException</code> if the authentication attempt fails
//      */
//     public void login(String username, String password, boolean rememberme);
// 
//     /**
//      * Persists current state of a specified <code>User</code> object.
//      * 
//      * @param user the <code>User</code> object
//      */
//     public void save(User user);
// 
// }


import javax.inject.Inject;
import javax.inject.Singleton;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.lbogdanov.poker.core.User;
import org.lbogdanov.poker.core.UserService;
import org.scribe.up.profile.google2.Google2Profile;
import com.avaje.ebean.EbeanServer;
import com.avaje.ebean.annotation.Transactional;
package org.lbogdanov.poker.core.impl;





/**
 * Implementation of {@link UserService} interface.
 * 
 * @author Leonid Bogdanov
 */
@Singleton
public class UserServiceImpl implements UserService {

    private static final Object USER_KEY = "USER_KEY";

    @Inject
    private EbeanServer ebean;

    /**
     * {@inheritDoc}
     */
    @Override
// Path: src/main/java/org/lbogdanov/poker/core/User.java
// @Entity
// @Table(name = "USERS")
// public class User extends AbstractEntity {
// 
//     @Column(name = "FIRST_NAME", length = USER_FIRST_NAME_MAX_LENGTH, nullable = false)
//     private String firstName = "";
//     @Column(name = "LAST_NAME", length = USER_LAST_NAME_MAX_LENGTH, nullable = true)
//     private String lastName = "";
//     @Column(name = "EMAIL", length = USER_EMAIL_MAX_LENGTH, nullable = true)
//     private String email = "";
//     @Column(name = "EXTERNAL_ID", length = USER_EXTERNAL_ID_MAX_LENGTH, nullable = false, unique = true)
//     private String externalId = "";
// 
//     /**
//      * Returns a user's first name.
//      * 
//      * @return the firstName
//      */
//     public String getFirstName() {
//         return firstName;
//     }
// 
//     /**
//      * Sets a user's first name, only the first {@link Constants.USER_FIRST_NAME_MAX_LENGTH} characters are stored.
//      * 
//      * @param firstName the first name to set
//      */
//     public void setFirstName(String firstName) {
//         this.firstName = limitString(firstName, USER_FIRST_NAME_MAX_LENGTH);
//     }
// 
//     /**
//      * Returns a user's last name.
//      * 
//      * @return the last name
//      */
//     public String getLastName() {
//         return lastName;
//     }
// 
//     /**
//      * Sets a user's last name, only the first {@link Constants.USER_LAST_NAME_MAX_LENGTH} characters are stored.
//      * 
//      * @param lastName the last name to set
//      */
//     public void setLastName(String lastName) {
//         this.lastName = limitString(lastName, USER_LAST_NAME_MAX_LENGTH);
//     }
// 
//     /**
//      * Returns a user's e-mail.
//      * 
//      * @return the e-mail
//      */
//     public String getEmail() {
//         return email;
//     }
// 
//     /**
//      * Sets a user's e-mail, only the first {@link Constants.USER_EMAIL_MAX_LENGTH} characters are stored.
//      * 
//      * @param email the e-mail to set
//      */
//     public void setEmail(String email) {
//         this.email = limitString(email, USER_EMAIL_MAX_LENGTH);
//     }
// 
//     /**
//      *  Returns a user's ID in an external system from which the user originates.
//      * 
//      * @return the external ID
//      */
//     public String getExternalId() {
//         return externalId;
//     }
// 
//     /**
//      * Sets a user's ID in an external system, only the first {@link Constants.USER_EXTERNAL_ID_MAX_LENGTH} characters are stored.
//      * 
//      * @param externalId the external ID
//      */
//     public void setExternalId(String externalId) {
//         this.externalId = limitString(externalId, USER_EXTERNAL_ID_MAX_LENGTH);
//     }
// 
//     /**
//      * {@inheritDoc}
//      */
//     @Override
//     public int hashCode() {
//         return Objects.hashCode(getExternalId());
//     }
// 
//     /**
//      * {@inheritDoc}
//      */
//     @Override
//     public boolean equals(Object obj) {
//         if (this == obj) {
//             return true;
//         }
//         if (obj instanceof User) {
//             User other = (User) obj;
//             return Objects.equal(this.getExternalId(), other.getExternalId());
//         }
//         return false;
//     }
// 
// }
// 
// Path: src/main/java/org/lbogdanov/poker/core/UserService.java
// public interface UserService {
// 
//     /**
//      * Returns currently logged in <code>User</code> instance.
//      * 
//      * @return the <code>User</code> object or <code>null</code> for an anonymous user
//      */
//     public User getCurrentUser();
// 
//     /**
//      * Performs a login attempt with specified credentials.
//      * 
//      * @param username the user name
//      * @param password the password
//      * @param rememberme  if a user identity should be remembered across sessions
//      * @throws <code>RuntimeException</code> if the authentication attempt fails
//      */
//     public void login(String username, String password, boolean rememberme);
// 
//     /**
//      * Persists current state of a specified <code>User</code> object.
//      * 
//      * @param user the <code>User</code> object
//      */
//     public void save(User user);
// 
// }


// Path: src/main/java/org/lbogdanov/poker/core/impl/UserServiceImpl.java
import javax.inject.Inject;
import javax.inject.Singleton;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.lbogdanov.poker.core.User;
import org.lbogdanov.poker.core.UserService;
import org.scribe.up.profile.google2.Google2Profile;
import com.avaje.ebean.EbeanServer;
import com.avaje.ebean.annotation.Transactional;

package org.lbogdanov.poker.core.impl;





/**
 * Implementation of {@link UserService} interface.
 * 
 * @author Leonid Bogdanov
 */
@Singleton
public class UserServiceImpl implements UserService {

    private static final Object USER_KEY = "USER_KEY";

    @Inject
    private EbeanServer ebean;

    /**
     * {@inheritDoc}
     */
    @Override
    public User getCurrentUser() {