context: using System;
  using System.Collections.Generic;
  using System.Diagnostics;
  using System.Linq;
  using System.Xml;
  using SmartStore.Core.Domain.Customers;
  using SmartStore.Core.Domain.Orders;
  using SmartStore.Core.Infrastructure;
  using SmartStore.Services.Common;
  using SmartStore.Services.Localization;
  using SmartStore.Services.Orders;
  
  namespace SmartStore.Services.Customers
  {
      public static class CustomerExtentions
      {
          /// <summary>
          /// Gets a value indicating whether customer is in a certain customer role
          /// </summary>
          /// <param name="customer">Customer</param>
          /// <param name="customerRoleSystemName">Customer role system name</param>
          /// <param name="onlyActiveCustomerRoles">A value indicating whether we should look only in active customer roles</param>
          /// <returns>Result</returns>
          public static bool IsInCustomerRole(this Customer customer, string customerRoleSystemName, bool onlyActiveCustomerRoles = true)
          {
              if (customer == null)
                  throw new ArgumentNullException("customer");
  
              if (String.IsNullOrEmpty(customerRoleSystemName))
                  throw new ArgumentNullException("customerRoleSystemName");
  
              var result = customer.CustomerRoles
                  .Where(cr => !onlyActiveCustomerRoles || cr.Active)
                  .Where(cr => cr.SystemName == customerRoleSystemName)
                  .FirstOrDefault() != null;
              return result;
          }
  
          /// <summary>
          /// Gets a value indicating whether the customer is a built-in record for background tasks
          /// </summary>
          /// <param name="customer">Customer</param>
          /// <returns>Result</returns>
          public static bool IsBackgroundTaskAccount(this Customer customer)
          {
  			Guard.ArgumentNotNull(() => customer);
  
  			if (!customer.IsSystemAccount || customer.SystemName.IsEmpty())
  				return false;
  
              var result = customer.SystemName.Equals(SystemCustomerNames.BackgroundTask, StringComparison.InvariantCultureIgnoreCase);
              return result;
          }
  
          /// <summary>
          /// Gets a value indicating whether customer a search engine
          /// </summary>
          /// <param name="customer">Customer</param>
          /// <returns>Result</returns>
          public static bool IsSearchEngineAccount(this Customer customer)
          {
  			Guard.ArgumentNotNull(() => customer);
  
  			if (!customer.IsSystemAccount || customer.SystemName.IsEmpty())
  				return false;
  
              var result = customer.SystemName.Equals(SystemCustomerNames.SearchEngine, StringComparison.InvariantCultureIgnoreCase);
              return result;
          }
  
  		/// <summary>
  		/// Gets a value indicating whether customer is the pdf converter
  		/// </summary>
  		/// <param name="customer">Customer</param>
  		/// <returns>Result</returns>
  		public static bool IsPdfConverter(this Customer customer)
  		{
  			Guard.ArgumentNotNull(() => customer);
  
  			if (!customer.IsSystemAccount || customer.SystemName.IsEmpty())
  				return false;
  
  			var result = customer.SystemName.Equals(SystemCustomerNames.PdfConverter, StringComparison.InvariantCultureIgnoreCase);
  			return result;
  		}
  
          /// <summary>
          /// Gets a value indicating whether customer is administrator
          /// </summary>
          /// <param name="customer">Customer</param>
          /// <param name="onlyActiveCustomerRoles">A value indicating whether we should look only in active customer roles</param>
          /// <returns>Result</returns>
          public static bool IsAdmin(this Customer customer, bool onlyActiveCustomerRoles = true)
          {
              return IsInCustomerRole(customer, SystemCustomerRoleNames.Administrators, onlyActiveCustomerRoles);
          }
  
  		/// <summary>
  		/// Gets a value indicating whether customer is super administrator
  		/// </summary>
  		/// <remarks>codehint: sm-add</remarks>
  		/// <param name="customer">Customer</param>
  		/// <param name="onlyActiveCustomerRoles">A value indicating whether we should look only in active customer roles</param>
  		/// <returns>Result</returns>
  		public static bool IsSuperAdmin(this Customer customer, bool onlyActiveCustomerRoles = true) {
  			return IsInCustomerRole(customer, SystemCustomerRoleNames.SuperAdministrators, onlyActiveCustomerRoles);
  		}
  
          /// <summary>
          /// Gets a value indicating whether customer is a forum moderator
          /// </summary>
          /// <param name="customer">Customer</param>
          /// <param name="onlyActiveCustomerRoles">A value indicating whether we should look only in active customer roles</param>
          /// <returns>Result</returns>
          public static bool IsForumModerator(this Customer customer, bool onlyActiveCustomerRoles = true)
          {
              return IsInCustomerRole(customer, SystemCustomerRoleNames.ForumModerators, onlyActiveCustomerRoles);
          }
  
          /// <summary>
          /// Gets a value indicating whether customer is registered
          /// </summary>
          /// <param name="customer">Customer</param>
          /// <param name="onlyActiveCustomerRoles">A value indicating whether we should look only in active customer roles</param>
          /// <returns>Result</returns>
          public static bool IsRegistered(this Customer customer, bool onlyActiveCustomerRoles = true)
          {
              return IsInCustomerRole(customer, SystemCustomerRoleNames.Registered, onlyActiveCustomerRoles);
          }
  
          /// <summary>
          /// Gets a value indicating whether customer is guest
          /// </summary>
          /// <param name="customer">Customer</param>
          /// <param name="onlyActiveCustomerRoles">A value indicating whether we should look only in active customer roles</param>
          /// <returns>Result</returns>
          public static bool IsGuest(this Customer customer, bool onlyActiveCustomerRoles = true)
          {
              return IsInCustomerRole(customer, SystemCustomerRoleNames.Guests, onlyActiveCustomerRoles);
          }
          
          public static string GetFullName(this Customer customer)
          {
              if (customer == null)
                  throw new ArgumentNullException("customer");
              var firstName = customer.GetAttribute<string>(SystemCustomerAttributeNames.FirstName);
              var lastName = customer.GetAttribute<string>(SystemCustomerAttributeNames.LastName);
  
              string fullName = "";
              if (!String.IsNullOrWhiteSpace(firstName) && !String.IsNullOrWhiteSpace(lastName))
              {
                  fullName = string.Format("{0} {1}", firstName, lastName);
              }
              else
              {
                  if (!String.IsNullOrWhiteSpace(firstName))
                      fullName = firstName;
  
                  if (!String.IsNullOrWhiteSpace(lastName))
                      fullName = lastName;
  
                  if (String.IsNullOrWhiteSpace(firstName) && String.IsNullOrWhiteSpace(lastName))
                  {
                      var address = customer.Addresses.FirstOrDefault();
                      if (address != null)
                          fullName = string.Format("{0} {1}", address.FirstName, address.LastName);
                  }
              }
              return fullName;
          }
  
          /// <summary>
          /// Formats the customer name
          /// </summary>
          /// <param name="customer">Source</param>
          /// <returns>Formatted text</returns>
          public static string FormatUserName(this Customer customer)
          {
              return FormatUserName(customer, false);
          }
  
          /// <summary>
          /// Formats the customer name
          /// </summary>
          /// <param name="customer">Source</param>
          /// <param name="stripTooLong">Strip too long customer name</param>
          /// <returns>Formatted text</returns>
          public static string FormatUserName(this Customer customer, bool stripTooLong)
          {
              if (customer == null)
                  return string.Empty;
  
              if (customer.IsGuest())
              {
                  return EngineContext.Current.Resolve<ILocalizationService>().GetResource("Customer.Guest");
              }
  
              string result = string.Empty;
              switch (EngineContext.Current.Resolve<CustomerSettings>().CustomerNameFormat)
              {
                  case CustomerNameFormat.ShowEmails:
                      result = customer.Email;
                      break;
                  case CustomerNameFormat.ShowFullNames:
                      result = customer.GetFullName();
                      break;
                  case CustomerNameFormat.ShowUsernames:
                      result = customer.Username;
                      break;
  				case CustomerNameFormat.ShowFirstName:
  					result = customer.GetAttribute<string>(SystemCustomerAttributeNames.FirstName);
  					break;
  				case CustomerNameFormat.ShowNameAndCity:
  					{
  						var firstName = customer.GetAttribute<string>(SystemCustomerAttributeNames.FirstName);
  						var lastName = customer.GetAttribute<string>(SystemCustomerAttributeNames.LastName);
  						var city = customer.GetAttribute<string>(SystemCustomerAttributeNames.City);
  
  						if (firstName.IsEmpty())
  						{
  							var address = customer.Addresses.FirstOrDefault();
  							if (address != null)
  							{
  								firstName = address.FirstName;
  								lastName = address.LastName;
  								city = address.City;
  							}
  						}
  
  						result = firstName;
  						if (lastName.HasValue())
  						{
  							result = "{0} {1}.".FormatWith(result, lastName.First());
  						}
  
  						if (city.HasValue())
  						{
  							var from = EngineContext.Current.Resolve<ILocalizationService>().GetResource("Common.ComingFrom");
  							result = "{0} {1} {2}".FormatWith(result, from, city);
  						}
  					}
  					break;
                  default:
                      break;
              }
  
  
gt:             if (stripTooLong && result.HasValue())