public void AddEmployee (EmployeeInfo employee, 
		    IList<OccupiedPositionInfo> occupiedPositions, 
            IList<EmployeeAchievementInfo> achievements,
            IList<EmployeeDisciplineInfo> eduPrograms)
        {
			using (var ctx = DataContext.Instance ())
			{
				ctx.BeginTransaction ();

				try
				{
					// add Employee
					Add<EmployeeInfo> (employee);

					// add new OccupiedPositions
					foreach (var op in occupiedPositions)
					{
						op.EmployeeID = employee.EmployeeID;
						Add<OccupiedPositionInfo> (op);
					}
					
					// add new EmployeeAchievements
					foreach (var ach in achievements)
					{
						ach.EmployeeID = employee.EmployeeID;
						Add<EmployeeAchievementInfo> (ach);
					}

                    // add new EmployeeEduPrograms
                    foreach (var ep in eduPrograms)
                    {
                        ep.EmployeeID = employee.EmployeeID;
                        Add<EmployeeDisciplineInfo> (ep);
                    }
				
					ctx.Commit ();
				}
				catch
				{
					ctx.RollbackTransaction ();
					throw;
				}
			}
		}
		/// <summary>
		/// Handles Click event for Update button
		/// </summary>
		/// <param name='sender'>
		/// Sender.
		/// </param>
		/// <param name='e'>
		/// Event args.
		/// </param>
		protected void buttonUpdate_Click (object sender, EventArgs e)
		{
			try
			{
				EmployeeInfo item;

				// determine if we are adding or updating
				// ALT: if (Null.IsNull (itemId))
				if (!itemId.HasValue)
				{
					// to add new record
					item = new EmployeeInfo ();
				}
				else
				{
					// update existing record
					item = EmployeeController.Get<EmployeeInfo> (itemId.Value);
				}

				// fill the object
				item.LastName = textLastName.Text.Trim ();
				item.FirstName = textFirstName.Text.Trim ();
				item.OtherName = textOtherName.Text.Trim ();
				item.Phone = textPhone.Text.Trim ();
				item.CellPhone = textCellPhone.Text.Trim ();
				item.Fax = textFax.Text.Trim ();
				item.Email = textEmail.Text.Trim ().ToLowerInvariant ();
				item.SecondaryEmail = textSecondaryEmail.Text.Trim ().ToLowerInvariant ();
				item.WebSite = textWebSite.Text.Trim ();
				item.WebSiteLabel = textWebSiteLabel.Text.Trim ();
				item.Messenger = textMessenger.Text.Trim ();
				item.WorkingPlace = textWorkingPlace.Text.Trim ();
				item.Biography = textBiography.Text.Trim ();
				
				// update working hours
				item.WorkingHours = WorkingHoursLogic.Update (comboWorkingHours, textWorkingHours.Text, 
                    checkAddToVocabulary.Checked);

				item.ExperienceYears = Utils.ParseToNullableInt (textExperienceYears.Text);
				item.ExperienceYearsBySpec = Utils.ParseToNullableInt (textExperienceYearsBySpec.Text);

				item.IsPublished = checkIsPublished.Checked;

				// pickerPhoto.FileID may be 0 by default
				item.PhotoFileID = (pickerPhoto.FileID > 0) ? (int?)pickerPhoto.FileID : null;
				item.UserID = Utils.ParseToNullableInt (comboUsers.SelectedValue);

				if (!itemId.HasValue)
				{		
					// update audit info
					item.CreatedByUserID = item.LastModifiedByUserID = this.UserId;
					item.CreatedOnDate = item.LastModifiedOnDate = DateTime.Now;
	
					// add employee
                    EmployeeController.AddEmployee (item, GetOccupiedPositions (), 
                        GetEmployeeAchievements (), GetEmployeeDisciplines());

					// then adding new employee from Employee or EmployeeDetails modules, 
					// set calling module to display new employee
					if (ModuleConfiguration.ModuleDefinition.DefinitionName == "R7.University.Employee" || 
                        ModuleConfiguration.ModuleDefinition.DefinitionName == "R7.University.EmployeeDetails")
					{
						EmployeeSettings.EmployeeID = item.EmployeeID;

						// we adding new employee, so he/she should be displayed in the module
						EmployeeSettings.ShowCurrentUser = false;
					}
				}
				else
				{
					// update audit info
					item.LastModifiedByUserID = this.UserId;
					item.LastModifiedOnDate = DateTime.Now;

					// update employee
                    EmployeeController.UpdateEmployee (item, GetOccupiedPositions (), 
                        GetEmployeeAchievements (), GetEmployeeDisciplines());
				}

                Utils.SynchronizeModule (this);
                DataCache.RemoveCache ("Employee_" + TabModuleId + "_RenderedContent");

                Response.Redirect (Globals.NavigateURL (), true);
			}
			catch (Exception ex)
			{
				Exceptions.ProcessModuleLoadException (this, ex);
			}
		}
		void Experience (EmployeeInfo employee)
		{
			// experience years
			var exp1 = false;
			var exp2 = false;
			var noExpYears = false;
			
			// Общий стаж работы (лет): {0}
			// Общий стаж работы по специальности (лет): {0}
			// Общий стаж работы (лет): {0}, из них по специальности: {1}
			
			if (employee.ExperienceYears != null && employee.ExperienceYears.Value > 0)
				exp1 = true;
			
			if (employee.ExperienceYearsBySpec != null && employee.ExperienceYearsBySpec.Value > 0)
				exp2 = true;
			
			if (exp1 && !exp2)
			{
				labelExperienceYears.Text = string.Format (
					LocalizeString ("ExperienceYears.Format1"), employee.ExperienceYears.Value);
			}
			else if (!exp1 && exp2)
			{
				labelExperienceYears.Text = string.Format (
					LocalizeString ("ExperienceYears.Format2"), employee.ExperienceYearsBySpec);
			}
			else if (exp1 && exp2)
			{
				labelExperienceYears.Text = string.Format (
					LocalizeString ("ExperienceYears.Format3"), 
					employee.ExperienceYears.Value, employee.ExperienceYearsBySpec);
			}
			else
			{
				// hide label for experience years
				labelExperienceYears.Visible = false;
				
				// about to hide Experience tab
				noExpYears = true;
			}

			// get all empoyee achievements
			var achievements = EmployeeController.GetObjects<EmployeeAchievementInfo> (CommandType.Text, 
                "SELECT * FROM dbo.vw_University_EmployeeAchievements WHERE [EmployeeID] = @0", employee.EmployeeID);
	
			// employee titles
            var titles = achievements.Where (ach => ach.IsTitle)
                .Select (ach => Utils.FirstCharToLower (ach.Title));
            
			var strTitles = Utils.FormatList (", ", titles);
			if (!string.IsNullOrWhiteSpace (strTitles))
				labelAcademicDegreeAndTitle.Text = Utils.FirstCharToUpper (strTitles);
			else
				labelAcademicDegreeAndTitle.Visible = false;

			// get only experience-related achievements
            var experiences = achievements
                .Where (ach => ach.AchievementType == AchievementType.Education ||
                    ach.AchievementType == AchievementType.AcademicDegree ||
                    ach.AchievementType == AchievementType.Training ||
                    ach.AchievementType == AchievementType.Work)
                .OrderByDescending (exp => exp.YearBegin);

			if (experiences.Any ())
			{
				gridExperience.DataSource = AchievementsDataTable (experiences);
				gridExperience.DataBind ();
			}
			else if (noExpYears)
			{
				// hide experience tab
				linkExperience.Visible = false;
			}
		
			// get all other achievements
            achievements = achievements
                .Where (ach => ach.AchievementType != AchievementType.Education &&
                    ach.AchievementType != AchievementType.AcademicDegree &&
                    ach.AchievementType != AchievementType.Training &&
                    ach.AchievementType != AchievementType.Work)
                .OrderByDescending (ach => ach.YearBegin);
			
            if (achievements.Any ())
			{
				gridAchievements.DataSource = AchievementsDataTable (achievements);
				gridAchievements.DataBind ();
			}
			else
			{	
				// hide achievements tab
				linkAchievements.Visible = false;
			}
		}
        void Barcode (EmployeeInfo employee)
		{
            linkBarcode.Attributes.Add ("data-module-id", ModuleId.ToString ());
            linkBarcode.Attributes.Add ("data-dialog-title", employee.FullName);

			// barcode image
			const int barcodeWidth = 192;
            imageBarcode.ImageUrl = R7.University.Utilities.UrlUtils.FullUrl (string.Format (
                "/imagehandler.ashx?barcode=1&width={0}&height={1}&type=qrcode&encoding=UTF-8&content={2}",
				barcodeWidth, barcodeWidth, 
				Server.UrlEncode (employee.VCard.ToString ()
						.Replace ("+", "%2b")) // fix for "+" signs in phone numbers
            ));

			imageBarcode.ToolTip = LocalizeString ("imageBarcode.ToolTip");
			imageBarcode.AlternateText = LocalizeString ("imageBarcode.AlternateText");
		}
        void EduPrograms (EmployeeInfo employee)
        {
            // get employee edu programs
            var disciplines = EmployeeController.GetObjects<EmployeeDisciplineInfoEx> (
                "WHERE [EmployeeID] = @0", employee.EmployeeID).OrderBy (d => d.Code);

            if (disciplines.Any ())
            {
                gridEduPrograms.DataSource = DataTableConstructor.FromIEnumerable (disciplines);
                gridEduPrograms.DataBind ();
            }
            else
            {
                linkDisciplines.Visible = false;
            }
        }
		protected void Display (EmployeeInfo employee)
		{
        	var fullname = employee.FullName;

            if (InPopup)
            {
                // set popup title to employee name
                ((DotNetNuke.Framework.CDefault) this.Page).Title = fullname;
            }
            else if (InViewModule)
            {
                if (EmployeeSettings.AutoTitle)
                    UpdateModuleTitle (employee.FullName);
            }
            else
            {
                // display employee name in label
                literalFullName.Text = "<h2>" + fullname + "</h2>";
            }

			// occupied positions
			var occupiedPositions = EmployeeController.GetObjects<OccupiedPositionInfoEx> (
                "WHERE [EmployeeID] = @0 ORDER BY [IsPrime] DESC, [PositionWeight] DESC", employee.EmployeeID);
            
			if (occupiedPositions.Any ())
			{
				repeaterPositions.DataSource = OccupiedPositionInfoEx.GroupByDivision (occupiedPositions);
				repeaterPositions.DataBind ();
			}
			else
				repeaterPositions.Visible = false;
			
            EmployeePhotoLogic.Bind (employee, imagePhoto, EmployeeSettings.PhotoWidth);
					
			// Phone
			if (!string.IsNullOrWhiteSpace (employee.Phone))
				labelPhone.Text = employee.Phone;
			else
				labelPhone.Visible = false;

			// CellPhome
			if (!string.IsNullOrWhiteSpace (employee.CellPhone))
				labelCellPhone.Text = employee.CellPhone;
			else
				labelCellPhone.Visible = false;

			// Fax
			if (!string.IsNullOrWhiteSpace (employee.Fax))
				labelFax.Text = string.Format (Localization.GetString ("Fax.Format", LocalResourceFile), employee.Fax);
			else
				labelFax.Visible = false;

			// Messenger
			if (!string.IsNullOrWhiteSpace (employee.Messenger))
				labelMessenger.Text = employee.Messenger;
			else
				labelMessenger.Visible = false;

			// Working place and Hours
			var workingPlaceAndHours = Utils.FormatList (", ", employee.WorkingPlace, employee.WorkingHours);
			if (!string.IsNullOrWhiteSpace (workingPlaceAndHours))
				labelWorkingPlaceAndHours.Text = workingPlaceAndHours;
			else
				labelWorkingPlaceAndHours.Visible = false;

			// WebSite
			if (!string.IsNullOrWhiteSpace (employee.WebSite))
			{
				linkWebSite.NavigateUrl = employee.FormatWebSiteUrl;
				linkWebSite.Text = employee.FormatWebSiteLabel;
			}
			else
				linkWebSite.Visible = false;

			// Email
			if (!string.IsNullOrWhiteSpace (employee.Email))
			{
				linkEmail.NavigateUrl = "mailto:" + employee.Email;
				linkEmail.Text = employee.Email;
			}
			else
				linkEmail.Visible = false;

			// Secondary email
			if (!string.IsNullOrWhiteSpace (employee.SecondaryEmail))
			{
				linkSecondaryEmail.NavigateUrl = "mailto:" + employee.SecondaryEmail;
				linkSecondaryEmail.Text = employee.SecondaryEmail;
			}
			else
				linkSecondaryEmail.Visible = false;

			// Profile link
			if (!Utils.IsNull<int> (employee.UserID))
				linkUserProfile.NavigateUrl = Globals.UserProfileURL (employee.UserID.Value);
			else
				linkUserProfile.Visible = false;

			// about
			if (!string.IsNullOrWhiteSpace (employee.Biography))
				litAbout.Text = Server.HtmlDecode (employee.Biography);
			else
			{
				// hide entire About tab
				linkAbout.Visible = false;
			}
			
            Experience (employee);
            EduPrograms (employee);
            Barcode (employee);
		}
		/// <summary>
		/// Imports a module from an XML
		/// </summary>
		/// <param name="ModuleID"></param>
		/// <param name="Content"></param>
		/// <param name="Version"></param>
		/// <param name="UserID"></param>
		public void ImportModule (int ModuleID, string Content, string Version, int UserID)
		{
			var infos = DotNetNuke.Common.Globals.GetContent (Content, "Employees");
		
			foreach (XmlNode info in infos.SelectNodes("Employee"))
			{
				var item = new EmployeeInfo ();

				item.LastName = info.SelectSingleNode ("lastname").InnerText;
				item.CreatedByUserID = UserID;

				Add<EmployeeInfo> (item);
			}
		}
		public void UpdateEmployee (EmployeeInfo employee, 
		    IList<OccupiedPositionInfo> occupiedPositions, 
            IList<EmployeeAchievementInfo> achievements,
            IList<EmployeeDisciplineInfo> disciplines)
        {
			using (var ctx = DataContext.Instance ())
			{
				ctx.BeginTransaction ();

				try
				{
					// update Employee
					Update<EmployeeInfo> (employee);

					var occupiedPositonIDs = occupiedPositions.Select (op => op.OccupiedPositionID.ToString ());
					if (occupiedPositonIDs.Any())
					{
						Delete<OccupiedPositionInfo> (
							string.Format ("WHERE [EmployeeID] = {0} AND [OccupiedPositionID] NOT IN ({1})", 
								employee.EmployeeID, Utils.FormatList (", ", occupiedPositonIDs))); 
					}
					else
					{
						// delete all employee occupied positions 
						Delete<OccupiedPositionInfo> ("WHERE [EmployeeID] = @0", employee.EmployeeID); 
					}
					
					// add new OccupiedPositions
					foreach (var op in occupiedPositions)
					{
						// REVIEW: Do we really need to set EmployeeID here?
						op.EmployeeID = employee.EmployeeID;
						
						if (op.OccupiedPositionID <= 0)
							Add<OccupiedPositionInfo> (op);
						else
							Update<OccupiedPositionInfo> (op);
					}
					
					var employeeAchievementIDs = achievements.Select (a => a.EmployeeAchievementID.ToString ());
					if (employeeAchievementIDs.Any())
					{
						// delete those not in current list
						Delete<EmployeeAchievementInfo> (
							string.Format ("WHERE [EmployeeID] = {0} AND [EmployeeAchievementID] NOT IN ({1})", 
								employee.EmployeeID, Utils.FormatList (", ", employeeAchievementIDs))); 
					}
					else
					{
						// delete all employee achievements
						Delete<EmployeeAchievementInfo> ("WHERE [EmployeeID] = @0", employee.EmployeeID);
					}

					// add new EmployeeAchievements
					foreach (var ach in achievements)
					{
						if (ach.AchievementID != null)
						{
							// reset linked properties
							ach.Title = null;
							ach.ShortTitle = null;
							ach.AchievementType = null;
						}
						
						ach.EmployeeID = employee.EmployeeID;
						if (ach.EmployeeAchievementID <= 0)
							Add<EmployeeAchievementInfo> (ach);
						else
							Update<EmployeeAchievementInfo> (ach);
					}

                    var employeeDisciplineIDs = disciplines.Select (a => a.EmployeeDisciplineID.ToString ());
                    if (employeeDisciplineIDs.Any ())
                    {
                        // delete those not in current list
                        Delete<EmployeeDisciplineInfo> (
                            string.Format ("WHERE [EmployeeID] = {0} AND [EmployeeDisciplineID] NOT IN ({1})", 
                                employee.EmployeeID, Utils.FormatList (", ", employeeDisciplineIDs))); 
                    }
                    else
                    {
                        // delete all employee disciplines
                        Delete<EmployeeDisciplineInfo> ("WHERE [EmployeeID] = @0", employee.EmployeeID);
                    }

                    // add new employee disciplines
                    foreach (var discipline in disciplines)
                    {
                        discipline.EmployeeID = employee.EmployeeID;
                        if (discipline.EmployeeDisciplineID <= 0)
                            Add<EmployeeDisciplineInfo> (discipline);
                        else
                            Update<EmployeeDisciplineInfo> (discipline);
                    }

					ctx.Commit ();
				}
				catch
				{
					ctx.RollbackTransaction ();
					throw;
				}
			}
		}
		/// <summary>
		/// Displays the specified employee.
		/// </summary>
		/// <param name="employee">Employee.</param>
		protected void Display (EmployeeInfo employee, IEnumerable<EmployeeAchievementInfo> achievements)
		{
			// occupied positions
			var occupiedPositions = EmployeeController.GetObjects<OccupiedPositionInfoEx> ("WHERE [EmployeeID] = @0 ORDER BY [IsPrime] DESC, [PositionWeight] DESC", employee.EmployeeID);
			if (occupiedPositions.Any ())
			{
				repeaterPositions.DataSource = OccupiedPositionInfoEx.GroupByDivision (occupiedPositions);
				repeaterPositions.DataBind ();
			}
			else
				repeaterPositions.Visible = false;

			// Full name
			var fullName = employee.FullName;
			labelFullName.Text = fullName;

            EmployeePhotoLogic.Bind (employee, imagePhoto, EmployeeSettings.PhotoWidth);

            // imagePhoto.Attributes.Add("onclick", Utils.EditUrl (this, "EmployeeDetails", "employee_id", EmployeeID.ToString ()));
			var popupUrl = Utils.EditUrl (this, "EmployeeDetails", "employee_id", employee.EmployeeID.ToString ());
				
			// alter popup window height
			linkPhoto.NavigateUrl = popupUrl.Replace ("550,950", "450,950");

			/* // Old academic degree & title
			var degreeAndTitle = Utils.FormatList (", ", employee.AcademicDegree, employee.AcademicTitle);
			if (!string.IsNullOrWhiteSpace (degreeAndTitle))
				labelAcademicDegreeAndTitle.Text = "&nbsp;&ndash; " + degreeAndTitle;
			else
				labelAcademicDegreeAndTitle.Visible = false;
			*/
			
			// Employee titles
			var titles = achievements.Select (ach => Utils.FirstCharToLower (ach.DisplayShortTitle)).ToList ();
			
			// add academic degree and title for backward compatibility
			titles.Add (employee.AcademicDegree);
			titles.Add (employee.AcademicTitle);
	
			var strTitles = Utils.FormatList (", ", titles);
			if (!string.IsNullOrWhiteSpace (strTitles))
				labelAcademicDegreeAndTitle.Text = "&nbsp;&ndash; " + strTitles;
			else
				labelAcademicDegreeAndTitle.Visible = false;
	
			// Phone
			if (!string.IsNullOrWhiteSpace (employee.Phone))
				labelPhone.Text = employee.Phone;
			else
				labelPhone.Visible = false;

			// CellPhome
			if (!string.IsNullOrWhiteSpace (employee.CellPhone))
				labelCellPhone.Text = employee.CellPhone;
			else
				labelCellPhone.Visible = false;

			// Fax
			if (!string.IsNullOrWhiteSpace (employee.Fax))
				labelFax.Text = string.Format (Localization.GetString ("Fax.Format", LocalResourceFile), employee.Fax);
			else
				labelFax.Visible = false;

			// Messenger
			if (!string.IsNullOrWhiteSpace (employee.Messenger))
				labelMessenger.Text = employee.Messenger;
			else
				labelMessenger.Visible = false;

			// Working place and Hours
			var workingPlaceAndHours = Utils.FormatList (", ", employee.WorkingPlace, employee.WorkingHours);
			if (!string.IsNullOrWhiteSpace (workingPlaceAndHours))
				labelWorkingPlaceAndHours.Text = workingPlaceAndHours;
			else
				labelWorkingPlaceAndHours.Visible = false;

			/*
			// Working place
			if (!string.IsNullOrWhiteSpace (employee.WorkingPlace))
				labelWorkingPlace.Text = employee.WorkingPlace;
			else
				labelWorkingPlace.Visible = false;

			// Working hours
			if (!string.IsNullOrWhiteSpace (employee.WorkingHours))
				labelWorkingHours.Text = employee.WorkingHours;
			else
				labelWorkingHours.Visible = false;
			*/

			/*
			// WebSite
			if (!string.IsNullOrWhiteSpace (employee.WebSite))
			{
				// THINK: Do we have to check if WebSite starting with http:// or https://?
				linkWebSite.NavigateUrl = "http://" + employee.WebSite;
				linkWebSite.Text = employee.WebSite;
			}
			else
				linkWebSite.Visible = false;
			*/

			// WebSite
			if (!string.IsNullOrWhiteSpace (employee.WebSite))
			{
				linkWebSite.NavigateUrl = employee.FormatWebSiteUrl;
				linkWebSite.Text = employee.FormatWebSiteLabel;
			}
			else
				linkWebSite.Visible = false;

			// Email
			if (!string.IsNullOrWhiteSpace (employee.Email))
			{
				linkEmail.NavigateUrl = "mailto:" + employee.Email;
				linkEmail.Text = employee.Email;
			}
			else
				linkEmail.Visible = false;

			// Secondary email
			if (!string.IsNullOrWhiteSpace (employee.SecondaryEmail))
			{
				linkSecondaryEmail.NavigateUrl = "mailto:" + employee.SecondaryEmail;
				linkSecondaryEmail.Text = employee.SecondaryEmail;
			}
			else
				linkSecondaryEmail.Visible = false;

			// Profile link
			if (!Utils.IsNull<int> (employee.UserID))
				linkUserProfile.NavigateUrl = Globals.UserProfileURL (employee.UserID.Value);
			else
				linkUserProfile.Visible = false;
		}
        void Barcode (EmployeeInfo employee)
		{
			// barcode image test
			var barcodeWidth = 150;
            imageBarcode.ImageUrl = R7.University.Utilities.UrlUtils.FullUrl (string.Format (
                "/imagehandler.ashx?barcode=1&width={0}&height={1}&type=qrcode&encoding=UTF-8&content={2}",
				barcodeWidth, barcodeWidth, 
				Server.UrlEncode (employee.VCard.ToString ()
						.Replace ("+", "%2b")) // fix for "+" signs in phone numbers
            ));

			imageBarcode.ToolTip = LocalizeString ("imageBarcode.ToolTip");
			imageBarcode.AlternateText = LocalizeString ("imageBarcode.AlternateText");
		}
        void EduPrograms (EmployeeInfo employee)
        {
            // get employee edu programs
            var eduPrograms = EmployeeController.GetObjects<EmployeeEduProgramInfoEx> (
                                  "WHERE [EmployeeID] = @0", employee.EmployeeID);

            if (eduPrograms.Any ())
            {
                gridEduPrograms.DataSource = EduProgramsTable (eduPrograms.OrderBy (ep => ep.Code));
                gridEduPrograms.DataBind ();
            }
            else
            {
                gridEduPrograms.Visible = false;

                // disciplines
                if (!string.IsNullOrWhiteSpace (employee.Disciplines))
                    litDisciplines.Text = Server.HtmlDecode (employee.Disciplines);
                else
                {
                    // hide entire Disciplines tab
                    linkDisciplines.Visible = false;
                }
            }
        }
        public static void Bind (EmployeeInfo employee, Image imagePhoto, int photoWidth, bool square = false)
        {
            IFileInfo image = null;
            var imageHeight = 0;
            var imageWidth = 0;

            if (!Utils.IsNull (employee.PhotoFileID))
            {
                // REVIEW: Need add ON DELETE rule to FK, linking PhotoFileID & Files.FileID 

                image = FileManager.Instance.GetFile (employee.PhotoFileID.Value);

                if (image != null && square)
                {
                    // trying to get square image
                    // FIXME: Remove hard-coded photo filename options
                    var squareImage = FileManager.Instance.GetFile(
                        FolderManager.Instance.GetFolder (image.FolderId), 
                        Path.GetFileNameWithoutExtension (image.FileName) + "_square" + Path.GetExtension(image.FileName));

                    if (squareImage != null)
                        image = squareImage;
                }
            }

            if (image != null)
            {
                imageHeight = image.Height;
                imageWidth = image.Width;

                // do we need to scale image?
                if (!Null.IsNull (photoWidth) && photoWidth != imageWidth)
                {
                    imagePhoto.ImageUrl = R7.University.Utilities.UrlUtils.FullUrl (string.Format (
                        "/imagehandler.ashx?fileid={0}&width={1}", image.FileId, photoWidth));
                }
                else
                {
                    // use original image
                    imagePhoto.ImageUrl = FileManager.Instance.GetUrl(image);
                }
            }
            else
            {
                // if not photo specified, or not found, use fallback image
                imageWidth = square ? 120 : 192;
                imageHeight = square ? 120 : 256;

                // TODO: Make fallback image resizable through image handler
                imagePhoto.ImageUrl = string.Format ("/DesktopModules/R7.University/R7.University/images/nophoto_{0}{1}.png", 
                    CultureInfo.CurrentCulture.TwoLetterISOLanguageName, square ? "_square" : "");
            }

            // do we need to scale image dimensions?
            if (!Null.IsNull (photoWidth) && photoWidth != imageWidth)
            {
                imagePhoto.Width = photoWidth;
                imagePhoto.Height = (int)(imageHeight * (float)photoWidth / imageWidth);
            }
            else
            {
                imagePhoto.Width = imageWidth;
                imagePhoto.Height = imageHeight;
            }

            // set alt & title for photo
            var fullName = employee.FullName;
            imagePhoto.AlternateText = fullName;
            imagePhoto.ToolTip = fullName;
        }