private RecTransportVehicleStd LoadVehicleStdDetails( RecTransportVehicleStd record )
		{
			if( record == null )
			{
				throw new ArgumentNullException( "VehicleStd" );
			}

			ImpactQuery query = new ImpactQuery()
			{
				Select =
				{
					ImpTransportVehicleStd.Name,
					ImpTransportVehicleStd.Description,
					ImpTransportVehicleStd.MaxLength,
					ImpTransportVehicleStd.MaxWidth,
					ImpTransportVehicleStd.MaxHeight,
					ImpTransportVehicleStd.MaxMass,
					ImpTransportVehicleStd.VehicleType,
					ImpTransportVehicleStd.TransportType,
				},
				From = { ImpTransportVehicleStd.As( "T1" ) },
				Where = { ImpTransportVehicleStd.Factory.Equal( record.Factory ), 
						  ImpTransportVehicleStd.Project.Equal( record.Factory ),  
						  ImpTransportVehicleStd.Name.Equal( record.Name)}
			};

			string statement = query.ToString();

			RecTransportVehicleStd result;

			using( ImpactDatabase database = new ImpactDatabase() )
			{
				result = database.GetFirst<RecTransportVehicleStd>( statement, column =>
				{
					return new RecTransportVehicleStd()
					{
						Factory = record.Factory,
						Project = record.Project,

						Name = DataConverter.Cast<string>( column[0] ),
						Description = DataConverter.Cast<string>( column[1] ),
						MaxLength = DataConverter.Cast<double>( column[2] ),
						MaxWidth = DataConverter.Cast<double>( column[3] ),
						MaxHeight = DataConverter.Cast<double>( column[4] ),
						MaxMass = DataConverter.Cast<double>( column[5] ),
						VehicleType = DataConverter.Cast<int>( column[6] ),
						TransportType = DataConverter.Cast<int>( column[7] ),
					};
				} );
			}

			if( result != null )
			{
				result.Factory = record.Factory;
				result.Project = record.Project;
				result.TransportType = record.TransportType; // Hmm which one should be used?
				result.VehicleId = record.VehicleId;
				result.TransportId = record.TransportId;
			}
			return result;
		}
		//public List<RecProductionFormStrandStd> LoadFormStrandStd( RecProductionFormStd rec )
		//{
		//    ImpactQuery query = new ImpactQuery()
		//    {
		//        Select =
		//        {
		//            //ImpProductionFormStrandStd.Name,
		//            ImpProductionFormStrandStd.StrandPos,
		//            ImpProductionFormStrandStd.StrandX,
		//            ImpProductionFormStrandStd.StrandY,
		//            ImpProductionFormStrandStd.StrandDimension, 
		//            ImpProductionFormStrandStd.StrandQuality, 
		//            ImpProductionFormStrandStd.StrandPrestressing, 
		//        },
		//        From = { ImpProductionFormStrandStd.As( "STD" ) },

		//        Where =
		//        {
		//            ImpProductionFormStrandStd.Factory.Equal( rec.Factory ),
		//            ImpProductionFormStrandStd.Project.Equal( rec.Factory ),
		//            ImpProductionFormStrandStd.Name.Equal( rec.Name ), //Form name
		//        },
		//        OrderBy = 
		//        { 
		//            { ImpProductionFormStrandStd.StrandPos },
		//        },
		//    };
		//    string statement = query.ToString();
		//    List<RecProductionFormStrandStd> result;

		//    using( ImpactDatabase database = new ImpactDatabase() )
		//    {
		//        result = database.GetAll( statement, FormStrandParse );
		//    }

		//    return result;
		//}

		//public static RecProductionFormStrandStd FormStrandParse( DbDataReader column )
		//{
		//    var record = new RecProductionFormStrandStd();
		//    //record.Name = DataConverter.Cast<string>( column[0] );
		//    record.StrandPos = DataConverter.Cast<int>( column[0] );
		//    record.StrandX = DataConverter.Cast<double>( column[1] );
		//    record.StrandY = DataConverter.Cast<double>( column[2] );
		//    record.StrandDimension = DataConverter.Cast<double>( column[3] );
		//    record.StrandQuality = DataConverter.Cast<string>( column[4] );
		//    record.StrandPrestressing = DataConverter.Cast<double>( column[5] );
		//    return record;
		//}

		//public int DeleteFormStrandStd( RecProductionFormStd recProductionFormStd, RecProductionFormStrandStd recProductionFormStrandStd )
		//{
		//    return 0;
		//}

        private bool FindProductionFormStrand( RecProductionFormStrandStd record )
        {
			using( ImpactDatabase database = new ImpactDatabase() )
			{
				var query = new ImpactQuery()
				{
					From = { ImpProductionFormStrand.As( "T1" ) },
					Where =
					{
						ImpProductionFormStrand.Factory.Equal( record.Factory ),
						ImpProductionFormStrand.Project.Equal( record.Factory ),
						ImpProductionFormStrand.Form.Equal( record.Name ),
						ImpProductionFormStrand.Strand.Equal( record.StrandPos.ToString() ),
					},
				};

				var statement = query.ToString();
				record = database.GetFirst( statement, column => new RecProductionFormStrandStd() );
			}

			return record != null;
        }
        /// <summary>
        /// Loads all companies, factories and projects available to the specified user.
        /// </summary>
        /// <param name="user">
        /// </param>
        /// <returns>
        /// The StruSoft.Impact.Data.CompanyDataCollection.
        /// </returns>
        public static CompanyDataCollection Load( string user )
        {
            // Make sure the user name is in lower case. ( Doesn't matter for SQL Server, but might be needed for Ingres )
            user = user.ToLower();

            List<Company> result = new List<Company>();

            string statement = GetCompanyFactoryProjectQuery( user );

            ImpactQuery query = new ImpactQuery
                                {
                                    Select =
				{
					ImpUser.CurrentFactory, 
					ImpUser.CurrentProject
				},
                                    From = {
              ImpUser.As( "T1" ) 
           },
                                    Where = {
               ImpUser.Userid.Equal( user ) 
            },
                                };

            string userFactoryProject = query.ToString();

            CompanyDataCollection data = null;

            using( ImpactDatabase database = new ImpactDatabase() )
            {
                var tempDataList = database.GetAll( statement, column => new
                {
                    Company = column[0].Cast<string>(),
                    CompanyName = column[1].Cast<string>(),
                    Factory = column[2].Cast<string>(),
                    FactoryName = column[3].Cast<string>(),
                    Project = column[4].Cast<string>().Trim(),
                    ProjectName = column[5].Cast<string>(),
                    Description = column[6].Cast<string>(),
                    Date = column[7].Cast<DateTime?>(),
                    ProjectType = column[8].Cast<ProjectType>(),
                    Status = column[9].Cast<ProjectStatus>(),
                } );

                var phaseList = database.GetAll( GetAllProjectPhaseQuery( user ), column => new
                {
                    Factory = column[0].Cast<string>(),
                    Project = column[1].Cast<string>().Trim(),
                    Phase = column[2].Cast<string>().Trim(),
                } );

                result = ( from row in tempDataList
                           orderby row.Company.GetAlphaNumericOrderToken()
                           group row by new { row.Company, row.CompanyName } into companyGroup
                           select new Company( companyGroup.Key.Company, companyGroup.Key.CompanyName )
                           {
                               Factories =
                                 ( from row in companyGroup
                                   orderby row.Factory.GetAlphaNumericOrderToken()
                                   group row by new { row.Factory, row.FactoryName } into factoryGroup
                                   select new Factory( factoryGroup.Key.Factory, factoryGroup.Key.FactoryName )
                                   {
                                       Projects =
                                       ( from row in factoryGroup
                                         orderby row.Date descending
                                         // Find all phases mathching this project and the project's factory, select the phase and order by ascending.
                                         let phases =
                                             phaseList.FindAll( phase => phase.Factory == row.Factory && phase.Project == row.Project ).Select(
                                                 phase => phase.Phase ).OrderBy( phase => phase.GetAlphaNumericOrderToken() )
                                         select
                                             new Project( row.Project, row.ProjectName, row.Description, row.Date, row.ProjectType, row.Status,
                                                          phases.ToList() ) ).ToList()

                                   } ).ToList(),

                           } ).ToList();

                CurrentProject currentProject = database.GetFirst( userFactoryProject, column => new CurrentProject
                                                                                                 {
                                                                                                     User = user,
                                                                                                     Factory = column[0].Cast<string>(),
                                                                                                     Project = ( column[1].Cast<string>() ?? string.Empty ).Trim(),
                                                                                                 } );

                if( null == currentProject )
                {
                    data = new CompanyDataCollection( user, result );
                }
                else
                {
                    data = new CompanyDataCollection( currentProject, result );
                }
            }

            return data;
        }
        /// <summary>
        /// Loads all the data necessesary for creating the "Project Browser" tree.
        /// </summary>
        /// <param name="factory">
        /// Which factory the project belongs to.
        /// </param>
        /// <param name="project">
        /// Which project to load.
        /// </param>
        /// <returns>
        /// The <see cref="ProjectRootData"/>.
        /// </returns>
        public static ProjectRootData Load( string factory, string project )
        {
            ProjectRootData projectRoot = new ProjectRootData( factory, project.Trim() );

            project = Util.CorrectProjectName( project );
            string company = Util.FactoryToCompany( factory );

            using( ImpactDatabase database = new ImpactDatabase() )
            {
                var titleAndDescription = database.GetFirst( 
                    GetProjectInfoQuery( factory, project ).ToString(), 
                    column => new
                        {
                            Title = column[0].Cast<string>(),
                            Description = column[1].Cast<string>(),
                            FactoryName = column[2].Cast<string>()
                        } );

                projectRoot.Title = titleAndDescription.Title;
                projectRoot.Description = titleAndDescription.Description;
                projectRoot.FactoryName = titleAndDescription.FactoryName;

                // Get and set the element status standard.
                projectRoot.ElementStatusStandard = database.GetAll( 
                    GetElementStatusStandardQuery( company ), 
                    column => new ElementStatusStandard
                              {
                                  StatusId    = column[0].Cast<int>(),
                                  Description = column[1].Cast<string>(),
                                  ColorIndex  = column[2].Cast<int>(),
                              }

                    ).ToDictionary( item => item.StatusId );

                // Get all elements.
                var elementDataList = database.GetAll( GetProjectElementDataQuery( factory, project ), ReadElementData );

                foreach (var elementGroup in elementDataList.GroupBy(data => data.ElementMark) )
                {
                    var count = elementGroup.Count();
                    foreach (var elementData in elementGroup)
                    {
                        elementData.Quantity = count;
                    }
                }
                
                // Get all levels and buildings.
                var tempBuildingFloorList = database.GetAll( 
                    GetBuildingLevelDataQuery( factory, project ), 
                    column => new
                    {
                        Building             = column[0].Cast<string>().Trim(), 
                        FloorId              = column[1].Cast<int>(), 
                        FloorName            = column[2].Cast<string>(), 
                        ElevationFloor       = column[3].Cast<double>(), 
                        Topping              = column[4].Cast<double>(), 
                        FloorHeight          = column[5].Cast<double>(), 
                        FloorToHeadOfOpening = column[6].Cast<double>(), 
                        FloorToCeiling       = column[7].Cast<double>(), 
                        WallBlockUp          = column[8].Cast<double>(), 
                    });

                // Phases.
                projectRoot.Phases = database.GetAll( GetPhaseQuery( factory, project ), column => column[0].Cast<string>().Trim() ).OrderBy( x => x.GetAlphaNumericOrderToken() ).ToList();

                // Elevations.
                var elevationList = database.GetAll( GetElevationQuery( factory, project ).ToString(), column => column[0].Cast<string>().Trim() ).OrderBy( x => x.GetAlphaNumericOrderToken() ).ToList();

                var elementsGrouping = ( from row in elementDataList
                                         orderby row.ElementMark.GetAlphaNumericOrderToken() ascending
                                         group row by new { row.Building, row.FloorId, row.ElementType } into g
                                         select g ).ToList();

                var buildingDataList = ( from row in tempBuildingFloorList
                                         group row by new { row.Building } into buildingGroup
                                         orderby buildingGroup.Key.Building.GetAlphaNumericOrderToken()
                                         select new BuildingData( buildingGroup.Key.Building )
                                         {
                                             Levels =
                                               ( from level in buildingGroup
                                                 orderby level.ElevationFloor
                                                 select new LevelData
                                                        {
                                                     Building              = level.Building, 
                                                     Id                    = level.FloorId, 
                                                     Name                  = level.FloorName, 
                                                     Elevation             = level.ElevationFloor, 
                                                     Height                = level.FloorHeight, 
                                                     HeightToHeadOfOpening = level.FloorToHeadOfOpening, 
                                                     HeightToCeiling       = level.FloorToCeiling, 
                                                     WallBlockUp           = level.WallBlockUp, 

                                                     ElementCategories =
                                                         ( from elementGroup in elementsGrouping
                                                           where
                                                           elementGroup.Key.Building == level.Building &&
                                                           elementGroup.Key.FloorId == level.FloorId
                                                           select new ElementCategoryData( elementGroup.Key.ElementType, elementGroup.ToList() ) ).ToList()
                                                 }

                                                 ).ToList()
                                         }).ToList();

                // Set the building data list.
                projectRoot.Model = new ModelData( buildingDataList, elevationList );

                // Get Company Settings.
                CompanySettings companySettings = GetCompanySettings( company, database );

                projectRoot.CompanySettings = companySettings;
            }

            return projectRoot;
        }
        /// <summary>
        /// The get company settings.
        /// </summary>
        /// <param name="company">
        /// The company.
        /// </param>
        /// <param name="database">
        /// The database.
        /// </param>
        /// <returns>
        /// The StruSoft.Impact.V120.ProjectManager.Core.ProjectBrowser.CompanySettings.
        /// </returns>
        private static CompanySettings GetCompanySettings( string company, ImpactDatabase database )
        {
            string companySettingsQuery = GetCompanySettingsQuery( company ).ToString();

            string settingValue = database.GetFirst( companySettingsQuery, column => column[0].Cast<string>() );

            UnitSystemType unitSystem;

            CompanySettings companySettings = new CompanySettings();

            if( !Enum.TryParse( settingValue, true, out unitSystem ) )
            {
                // Default to metric if we failed conversion.
                unitSystem = UnitSystemType.Metric;

                // Since we could not find a unit system in the database for the specified company,
                // we must assume there are no company units either. So we create default company settings.
                companySettings.UnitSystem = unitSystem;

                foreach( var item in CreateDefaultUnitData( unitSystem ) )
                {
                    companySettings[item.Parameter] = item;
                }
            }
            else
            {
                companySettings.UnitSystem = unitSystem;

                // Get the company units from the database.
                string companyUnitsQuery = GetCompanyUnitsQuery( company ).ToString();

                var companyUnitList = database.GetAll( 
                    companyUnitsQuery, 
                    column =>
                        {
                            UnitParameter parameter;

                            if( !Enum.TryParse( column[0].Cast<string>(), true, out parameter ) )
                            {
                                return null;
                            }

                            UnitType unitType = column[1].Cast<UnitType>();

                            return new CompanyUnit( parameter, unitType, column[2].Cast<int>(), column[3].Cast<int>() );
                        });

                // Join the default unit data with the unit data from the database. If any unit is
                // missing from the database, then we'll use the default unit instead.
                var leftJoin = ( from defaultUnit in CreateDefaultUnitData( unitSystem )
                                 join databaseUnit in companyUnitList
                                     on defaultUnit.Parameter equals databaseUnit.Parameter into joinedList
                                 from companyUnit in joinedList.DefaultIfEmpty( defaultUnit )
                                 select companyUnit ).ToList();

                foreach( var item in leftJoin )
                {
                    companySettings[item.Parameter] = item;
                }
            }

            ImpactQuery dateFormatQuery = new ImpactQuery( true )
                {
                    From = {
                               ImpCompany.As( "T1" ) 
                           }, 
                    Select = {
                                 ImpCompany.DateFormat 
                             }, 
                    Where =
                        {
                            ImpCompany.Company.Equal( company ), 
                        }
                };

            var dateFormatList = database.GetAll( dateFormatQuery.ToString(), column => column[0].Cast<CompanyDateFormat>() );

            if( dateFormatList.Count > 0 )
            {
                companySettings.DateFormat = dateFormatList[0];
            }
            else
            {
                companySettings.DateFormat = CompanyDateFormat.Sweden;
            }

            return companySettings;
        }
		static public string GetCompany( string factory )
		{
			RecNumberGenerator record = null;
			using( ImpactDatabase database = new ImpactDatabase() )
			{
				ImpactQuery query = new ImpactQuery()
				{
					From = { ImpFactory.As( "T1" ) },
					Where =
					{
						ImpFactory.Factory.Equal( factory )
					},
				};

				string statement = query.ToString();

				record = database.GetFirst( statement, column => new RecNumberGenerator()
				{
					Factory = DataConverter.Cast<string>( column["COMPANY"] ),
				} );
			}
			return record.Factory;// In fact this is Company!!

		}
		/// <summary>
		/// Loads the required number generator object
		/// </summary>
		/// <param name="factory"></param>
		/// <param name="project"></param>
		/// <param name="variable"></param>
		/// <returns></returns>
		private RecNumberGenerator LoadRecord( string factory, string project, string variable )
		{
			RecNumberGenerator record = null;
			using( ImpactDatabase database = new ImpactDatabase() )
			{
				ImpactQuery query = new ImpactQuery()
				{
					From = { ImpNumGen.As( "T1" ) },
					Where =
					{
						ImpNumGen.Factory.Equal( factory ),
						ImpNumGen.Project.Equal( project ),
						ImpNumGen.Variable.Equal( variable ),
					},
				};

				string statement = query.ToString();

				record = database.GetFirst( statement, column => new RecNumberGenerator()
				{
					Factory = DataConverter.Cast<string>( column["FACTORY"] ),
					Project = DataConverter.Cast<string>( column["PROJECT"] ),
					Variable = DataConverter.Cast<string>( column["Variable"] ),
					Description = DataConverter.Cast<string>( column["Description"] ),
					UpperBound = DataConverter.Cast<int>( column["Upper_Bound"] ),
					LowerBound = DataConverter.Cast<int>( column["Lower_Bound"] ),
					NextNumber = DataConverter.Cast<int>( column["Next_Number"] ),
					ChangedDate = DataConverter.Cast<DateTime>( column["Changed_Date"] )
				} );
			}

			return record;
		}