static void Main()
        {
            Database.SetInitializer(new MigrateDatabaseToLatestVersion<OnlineBankContext, Configuration>());

            using (var context = new OnlineBankContext())
            {
                context.Database.Initialize(true);
            }
        }
        public HttpResponseMessage PostLoginUser(UserModel model)
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(
              () =>
              {
                  var context = new OnlineBankContext();
                  using (context)
                  {
                      this.ValidateUsername(model.DisplayName);
                      this.ValidateAuthCode(model.AuthCode);
                      var usernameToLower = model.DisplayName.ToLower();
                      var user = context.Users.FirstOrDefault(
                          usr => usr.Username == usernameToLower
                          && usr.AuthCode == model.AuthCode);

                      if (user == null)
                      {
                          throw new InvalidOperationException("Invalid username or password");
                      }
                      if (user.SessionKey == null)
                      {
                          user.SessionKey = this.GenerateSessionKey(user.Id);
                          context.SaveChanges();
                      }

                      var loggedModel = new LoggedUserModel()
                      {
                          DisplayName = user.Username,
                          SessionKey = user.SessionKey
                      };

                      var response =
                          this.Request.CreateResponse(HttpStatusCode.Created,
                                          loggedModel);
                      return response;
                  }
              });

            return responseMsg;
        }
        public HttpResponseMessage GetAccountsBySessionKey(string sessionKey)
        {
            var response = this.PerformOperationAndHandleExceptions(() =>
            {
                OnlineBankContext context = new OnlineBankContext();
                ValidateSessionKey(sessionKey, context);

                var accounts = (from account in context.Accounts.Include("Owner")
                                where account.Owner.SessionKey == sessionKey
                                select new AccountModel()
                                {
                                    Id = account.Id,
                                    Balance = account.Balance,
                                    OwnerName = account.Owner.Username
                                });

                var responseMsg =  Request.CreateResponse(HttpStatusCode.OK, accounts);

                return responseMsg;
            });

            return response;
        }
        public HttpResponseMessage DepositCash(int id, decimal depositSum, string sessionKey)
        {
            var response = this.PerformOperationAndHandleExceptions(() =>
            {
                OnlineBankContext context = new OnlineBankContext();
                this.ValidateSessionKey(sessionKey, context);

                var acc = (from account in context.Accounts.Include("Owner")
                           where account.Id == id && account.Owner.SessionKey == sessionKey
                           select account).FirstOrDefault();

                if (acc == null)
                {
                    throw new ArgumentException("Account not found.");
                }

                TransactionLog transactionLog = new TransactionLog()
                {
                    Account = acc,
                    LogDate = DateTime.Now,
                    LogText = string.Format("{0} deposited {1} money in {2}", acc.Owner.FullName, depositSum, acc.Id)
                };

                acc.Transactions.Add(transactionLog);
                context.TransactionLogs.Add(transactionLog);

                acc.Balance += depositSum;
                context.SaveChanges();

                var responseMsg = this.Request.CreateResponse(HttpStatusCode.OK, "OK");

                return responseMsg;
            });

            return response;
        }
        public HttpResponseMessage GetDetailedInformationAboutAnAccount(int id, string sessionKey)
        {
            var response = this.PerformOperationAndHandleExceptions(() =>
            {
                OnlineBankContext context = new OnlineBankContext();
                ValidateSessionKey(sessionKey, context);

                var acc = (from account in context.Accounts.Include("Owner")
                           where account.Id == id && account.Owner.SessionKey == sessionKey
                           select new FullAccountModel()
                           {
                               Id = account.Id,
                               Balance = account.Balance,
                               CreatedOn = account.CreatedOn,
                               ExpireDate = account.ExpireDate,
                               Owner = new LoggedUserModel()
                               {
                                   DisplayName = account.Owner.Username,
                                   SessionKey = account.Owner.SessionKey
                               },
                               Transactions = from transaction in account.Transactions
                                              select new TransactionLogModel()
                                              {
                                                  AccountId = account.Id,
                                                  LogDate = transaction.LogDate,
                                                  LogText = transaction.LogText,
                                                  UserFullName = account.Owner.FullName
                                              }
                           });

                var responseMsg = this.Request.CreateResponse(HttpStatusCode.OK, acc);

                return responseMsg;
            });

            return response;
        }
        protected void ValidateSessionKey(string sessionKey, OnlineBankContext context)
        {
            if (sessionKey.Length != SessionKeyLength)
            {
                throw new ArgumentException("The session key is of invalid length!");
            }

            var user = from u in context.Users
                       where u.SessionKey == sessionKey
                       select u;

            if (user == null)
            {
                throw new InvalidOperationException("Session key not found!");
            }
        }
        public HttpResponseMessage PutLogoutUser(string sessionKey)
        {
            var context = new OnlineBankContext();

            var user = context.Users.FirstOrDefault(u => u.SessionKey == sessionKey);

            user.SessionKey = null;
            context.SaveChanges();

            var response =
                          this.Request.CreateResponse(HttpStatusCode.OK);
            return response;
        }