#**************************************************************
#  
#  Licensed to the Apache Software Foundation (ASF) under one
#  or more contributor license agreements.  See the NOTICE file
#  distributed with this work for additional information
#  regarding copyright ownership.  The ASF licenses this file
#  to you under the Apache License, Version 2.0 (the
#  "License"); you may not use this file except in compliance
#  with the License.  You may obtain a copy of the License at
#  
#    http://www.apache.org/licenses/LICENSE-2.0
#  
#  Unless required by applicable law or agreed to in writing,
#  software distributed under the License is distributed on an
#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
#  KIND, either express or implied.  See the License for the
#  specific language governing permissions and limitations
#  under the License.
#  
#**************************************************************



package installer::packagelist;

use installer::converter;
use installer::exiter;
use installer::globals;
use installer::remover;
use installer::scriptitems;

########################################
# Check existence of module
########################################

sub check_module_existence
{
	my ($onegid, $moduleslist) = @_;

	my $foundgid = 0;

	for ( my $i = 0; $i <= $#{$moduleslist}; $i++ )
	{
		my $gid = ${$moduleslist}[$i]->{'gid'};
		
		if ( $gid eq $onegid )
		{
			$foundgid = 1;
			last;
		}
	}
	
	return $foundgid;
}

###################################################
# Analyzing the gids, defined in the packagelist
###################################################

sub analyze_list
{
	my ($packagelist, $moduleslist) = @_;
	
	@allpackages = ();
	
	my $moduleshash = get_module_hash($moduleslist);
	
	for ( my $i = 0; $i <= $#{$packagelist}; $i++ )
	{
		my $onepackage = ${$packagelist}[$i];
		
		my $onegid = $onepackage->{'module'};
		
		installer::remover::remove_leading_and_ending_whitespaces(\$onegid);

		my $moduleexists = check_module_existence($onegid, $moduleslist);

		if ( ! $moduleexists ) { next; }

		my @allmodules = ();

		push(@allmodules, $onegid);
		
		# get_children($moduleslist, $onegid, \@allmodules);
		get_children_with_hash($moduleshash, $onegid, \@allmodules);
		
		$onepackage->{'allmodules'} = \@allmodules;

		push(@allpackages, $onepackage);
	}

	return \@allpackages;
}

###################################################
# Creating a hash, that contains the module gids
# as keys and the parentids as values
###################################################

sub get_module_hash
{
	my ($moduleslist) = @_;
	
	my %modulehash = ();
	
	for ( my $i = 0; $i <= $#{$moduleslist}; $i++ )
	{
		my $gid = ${$moduleslist}[$i]->{'gid'};
		# Containing only modules with parent. Root modules can be ignored.
		if ( ${$moduleslist}[$i]->{'ParentID'} ) { $modulehash{$gid} = ${$moduleslist}[$i]->{'ParentID'}; }
	}
	
	return \%modulehash;
}

########################################################
# Recursively defined procedure to order 
# modules and directories
########################################################

sub get_children_with_hash
{
	my ($modulehash, $parentgid, $newitemorder) = @_;

	foreach my $gid ( keys %{$modulehash} )
	{
		my $parent = $modulehash->{$gid};

		if ( $parent eq $parentgid )
		{
			push(@{$newitemorder}, $gid);
			my $parent = $gid;
			get_children_with_hash($modulehash, $parent, $newitemorder);	# recursive!
		}		
	}
}

########################################################
# Recursively defined procedure to order 
# modules and directories
########################################################

sub get_children
{
	my ($allitems, $startparent, $newitemorder) = @_;

	for ( my $i = 0; $i <= $#{$allitems}; $i++ )
	{
		my $gid = ${$allitems}[$i]->{'gid'};
		my $parent = "";
		if ( ${$allitems}[$i]->{'ParentID'} ) { $parent = ${$allitems}[$i]->{'ParentID'}; }

		if ( $parent eq $startparent )
		{
			push(@{$newitemorder}, $gid);
			my $parent = $gid;
			get_children($allitems, $parent, $newitemorder);	# recursive!
		}
	}
}

#####################################################################
# All modules below a defined gid_Module_A are collected now for
# each modules defined in the packagelist. Now the modules have
# to be removed, that are part of more than one package.
#####################################################################

sub remove_multiple_modules_packages
{
	my ($allpackagemodules) = @_;

	# iterating over all packages

	for ( my $i = 0; $i <= $#{$allpackagemodules}; $i++ )
	{
		my $onepackage = ${$allpackagemodules}[$i];
		my $allmodules = $onepackage->{'allmodules'};

		# print "Modules below $onepackage->{'module'}: $#{$allmodules}\n";
		
		# Comparing each package, with all following packages. If a 
		# gid for the module is part of more than one package, it is 
		# removed if the number of modules in the package is greater
		# in the current package than in the compare package.
		
		# Taking all modules from package $i
		
		my $packagecount = $#{$allmodules};
		
		my @optimizedpackage = ();
		
		# iterating over all modules of this package

		for ( my $j = 0; $j <= $#{$allmodules}; $j++ )
		{
			my $onemodule = ${$allmodules}[$j];	# this is the module, that shall be removed or not
		
			my $put_module_into_new_package = 1;
		
			# iterating over all other packages	

			for ( my $k = 0; $k <= $#{$allpackagemodules}; $k++ )
			{
				if ( $k == $i ) { next; }	# not comparing equal module
				
				if (! $put_module_into_new_package) { next; } # do not compare, if already found

				my $comparepackage = ${$allpackagemodules}[$k];
				my $allcomparemodules = $comparepackage->{'allmodules'};

				my $comparepackagecount = $#{$allcomparemodules};

				# modules will only be removed from packages, that have more modules
				# than the compare package

				if ( $packagecount <= $comparepackagecount ) { next; }	# nothing to do, take next package

				# iterating over all modules of this package	

				for ( my $m = 0; $m <= $#{$allcomparemodules}; $m++ )
				{
					my $onecomparemodule = ${$allcomparemodules}[$m];
					
					if ( $onemodule eq $onecomparemodule )	# this $onemodule has to be removed
					{
						$put_module_into_new_package = 0;
					}
				}
			}
		
			if ( $put_module_into_new_package )
			{
				push(@optimizedpackage, $onemodule)
			}	
		}

		$onepackage->{'allmodules'} = \@optimizedpackage;	
	}

	# for ( my $i = 0; $i <= $#{$allpackagemodules}; $i++ )
	# {
	#	my $onepackage = ${$allpackagemodules}[$i];
	#	my $allmodules = $onepackage->{'allmodules'};
	#	print "New: Modules below $onepackage->{'module'}: $#{$allmodules}\n";
	# }
	
}

#####################################################################
# Analyzing all files if they belong to a special package.
# A package is described by a list of modules.
#####################################################################

sub find_files_for_package
{
	my ($filelist, $onepackage) = @_;

	my @newfilelist = ();

	for ( my $i = 0; $i <= $#{$filelist}; $i++ )
	{
		my $onefile = ${$filelist}[$i];
		my $modulesstring = $onefile->{'modules'};	 # comma separated modules list
		my $moduleslist = installer::converter::convert_stringlist_into_array(\$modulesstring, ",");

		my $includefile = 0;

		# iterating over all modules of this file

		for ( my $j = 0; $j <= $#{$moduleslist}; $j++ )
		{
			if ( $includefile ) { next; }
			my $filemodule = ${$moduleslist}[$j];
			installer::remover::remove_leading_and_ending_whitespaces(\$filemodule);
			
			# iterating over all modules of the package
			
			my $packagemodules = $onepackage->{'allmodules'};

			for ( my $k = 0; $k <= $#{$packagemodules}; $k++ )
			{
				if ( $includefile ) { next; }
				my $packagemodule = ${$packagemodules}[$k];
				
				if ( $filemodule eq $packagemodule )
				{
					$includefile = 1;
					last;
				}
			}
		}
	
		if ( $includefile )
		{
			push(@newfilelist, $onefile);	
		}
	}
	
	return \@newfilelist;
}

#####################################################################
# Analyzing all links if they belong to a special package.
# A package is described by a list of modules.
# A link is inserted into the package, if the corresponding
# file is also inserted.
#####################################################################

sub find_links_for_package
{
	my ($linklist, $filelist) = @_;
	
	# First looking for all links with a FileID.
	# Then looking for all links with a ShortcutID.

	my @newlinklist = ();

	for ( my $i = 0; $i <= $#{$linklist}; $i++ )
	{
		my $includelink = 0;

		my $onelink = ${$linklist}[$i];
	
		my $fileid = "";
		if ( $onelink->{'FileID'} ) { $fileid = $onelink->{'FileID'}; }
		
		if ( $fileid eq "" ) { next; }	 # A link with a ShortcutID
		
		for ( my $j = 0; $j <= $#{$filelist}; $j++ )	 # iterating over file list
		{
			my $onefile = ${$filelist}[$j];
			my $gid = $onefile->{'gid'};
		
			if ( $gid eq $fileid )
			{
				$includelink = 1;
				last;
			}
		}
		
		if ( $includelink )
		{
			push(@newlinklist, $onelink);	
		}
	}
	
	# iterating over the new list, because of all links with a ShortcutID

	for ( my $i = 0; $i <= $#{$linklist}; $i++ )
	{
		my $includelink = 0;

		my $onelink = ${$linklist}[$i];

		my $shortcutid = "";
		if ( $onelink->{'ShortcutID'} ) { $shortcutid = $onelink->{'ShortcutID'}; }
		
		if ( $shortcutid eq "" ) { next; }	 # A link with a ShortcutID

		for ( my $j = 0; $j <= $#newlinklist; $j++ )	 # iterating over newly created link list
		{
			my $onefilelink = $newlinklist[$j];
			my $gid = $onefilelink->{'gid'};
		
			if ( $gid eq $shortcutid )
			{
				$includelink = 1;
				last;
			}
		}
		
		if ( $includelink )
		{
			push(@newlinklist, $onelink);	
		}
	}

	return \@newlinklist;
}

#####################################################################
# Analyzing all directories if they belong to a special package.
# A package is described by a list of modules.
# Directories are included into the package, if they are needed
# by a file or a link included into the package. 
# Attention: A directory with the flag CREATE, is only included
# into the root module:
# ($packagename eq $installer::globals::rootmodulegid)
#####################################################################

sub find_dirs_for_package
{
	my ($dirlist, $onepackage) = @_;

	my @newdirlist = ();

	for ( my $i = 0; $i <= $#{$dirlist}; $i++ )
	{
		my $onedir = ${$dirlist}[$i];
		my $modulesstring = $onedir->{'modules'};	 # comma separated modules list
		my $moduleslist = installer::converter::convert_stringlist_into_array(\$modulesstring, ",");

		my $includedir = 0;

		# iterating over all modules of this dir

		for ( my $j = 0; $j <= $#{$moduleslist}; $j++ )
		{
			if ( $includedir ) { last; }
			my $dirmodule = ${$moduleslist}[$j];
			installer::remover::remove_leading_and_ending_whitespaces(\$dirmodule);
			
			# iterating over all modules of the package
			
			my $packagemodules = $onepackage->{'allmodules'};

			for ( my $k = 0; $k <= $#{$packagemodules}; $k++ )
			{
				my $packagemodule = ${$packagemodules}[$k];
				
				if ( $dirmodule eq $packagemodule )
				{
					$includedir = 1;
					last;
				}
			}
		}
	
		if ( $includedir )
		{
			push(@newdirlist, $onedir);	
		}
	}
	
	return \@newdirlist;
}

#####################################################################
# Resolving all variables in the packagename.
#####################################################################

sub resolve_packagevariables
{
	my ($packagenameref, $variableshashref, $make_lowercase) = @_;

	my $key;
	
	# Special handling for dictionaries
	if ( $$packagenameref =~ /-dict-/ )
	{
		if (exists($variableshashref->{'DICTIONARYUNIXPRODUCTNAME'}) ) { $$packagenameref =~ s/\%UNIXPRODUCTNAME/$variableshashref->{'DICTIONARYUNIXPRODUCTNAME'}/g; }
		if (exists($variableshashref->{'DICTIONARYBRANDPACKAGEVERSION'}) ) { $$packagenameref =~ s/\%BRANDPACKAGEVERSION/$variableshashref->{'DICTIONARYBRANDPACKAGEVERSION'}/g; }
	}
	
	foreach $key (keys %{$variableshashref})
	{								
		my $value = $variableshashref->{$key};
		if ( $make_lowercase ) { $value = lc($value); }
		$$packagenameref =~ s/\%$key/$value/g;
	}
}

#####################################################################
# Resolving all variables in the packagename.
#####################################################################

sub resolve_packagevariables2
{
	my ($packagenameref, $variableshashref, $make_lowercase, $isdict ) = @_;

	my $key;
	
	# Special handling for dictionaries
	if ( $isdict )
	{
		if (exists($variableshashref->{'DICTIONARYUNIXPRODUCTNAME'}) ) { $$packagenameref =~ s/\%UNIXPRODUCTNAME/$variableshashref->{'DICTIONARYUNIXPRODUCTNAME'}/g; }
		if (exists($variableshashref->{'DICTIONARYBRANDPACKAGEVERSION'}) ) { $$packagenameref =~ s/\%BRANDPACKAGEVERSION/$variableshashref->{'DICTIONARYBRANDPACKAGEVERSION'}/g; }
	}
	
	foreach $key (keys %{$variableshashref})
	{								
		my $value = $variableshashref->{$key};
		if ( $make_lowercase ) { $value = lc($value); }
		$$packagenameref =~ s/\%$key/$value/g;
	}
}

#####################################################################
# New packages system.
#####################################################################

##################################################################
# Controlling the content of the packagelist
# 1. Items in @installer::globals::packagelistitems must exist
# 2. If a shellscript file is defined, it must exist
##################################################################

sub check_packagelist
{
	my ($packages) = @_;
	
	if ( ! ( $#{$packages} > -1 )) { installer::exiter::exit_program("ERROR: No packages defined!", "check_packagelist"); }

	for ( my $i = 0; $i <= $#{$packages}; $i++ )
	{
		my $onepackage = ${$packages}[$i];
		
		my $element;

		# checking all items that must be defined
		
		foreach $element (@installer::globals::packagelistitems)
		{	
			if ( ! exists($onepackage->{$element}) )
			{
				installer::exiter::exit_program("ERROR in package list: No value for $element !", "check_packagelist");
			}			
		}

		# checking the existence of the script file, if defined

		if ( $onepackage->{'script'} )
		{
			my $scriptfile = $onepackage->{'script'};
			my $gid =  $onepackage->{'module'};
			my $fileref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$scriptfile, "" , 0);

			if ( $$fileref eq "" ) { installer::exiter::exit_program("ERROR: Could not find script file $scriptfile for module $gid!", "check_packagelist"); }

			$installer::logger::Lang->printf("%s: Using script file: \"%s\"!\n", $gid, $$fileref);

			$onepackage->{'script'} = $$fileref;
		}
	}
}

#####################################################################
# Reading pack info for one module from packinfo file.
#####################################################################

sub get_packinfo
{
	my ($gid, $filename, $packages, $onelanguage, $islanguagemodule) = @_;

	my $packagelist	= installer::files::read_file($filename);
	
	my @allpackages = ();
	
	for ( my $i = 0; $i <= $#{$packagelist}; $i++ )
	{
		my $line = ${$packagelist}[$i];

		if ( $line =~ /^\s*\#/ ) { next; }	# this is a comment line

		if ( $line =~ /^\s*Start\s*$/i ) 	# a new package definition
		{
			my %onepackage = ();

			my $counter = $i + 1;

			while (!( ${$packagelist}[$counter] =~ /^\s*End\s*$/i ))
			{
				if ( ${$packagelist}[$counter] =~ /^\s*(\S+)\s*\=\s*\"(.*)\"/ )
				{
					my $key = $1;
					my $value = $2;
					$onepackage{$key} = $value;							
				}
				
				$counter++;	
			}

			$onepackage{'islanguagemodule'} = $islanguagemodule;
			if ( $islanguagemodule )
			{
				$saveonelanguage = $onelanguage;
				$saveonelanguage =~ s/_/-/g;
				$onepackage{'language'} = $saveonelanguage;
			}
					
			push(@allpackages, \%onepackage);	
		}
	}
	
	# looking for the packinfo with the correct gid
	
	my $foundgid = 0;
	my $onepackage;
	foreach $onepackage (@allpackages)
	{
		# Adding the language to the module gid for LanguagePacks !
		# Making the module gid language specific: gid_Module_Root -> gir_Module_Root_pt_BR (as defined in scp2)
		if ( $onelanguage ne "" ) { $onepackage->{'module'} = $onepackage->{'module'} . "_$onelanguage"; }

		if ( $onepackage->{'module'} eq $gid )
		{
			# Resolving the language identifier
			my $onekey;
			foreach $onekey ( keys %{$onepackage} )
			{
				# Some keys require "-" instead of "_" for example in "en-US". All package names do not use underlines.
				my $locallang = $onelanguage;
				if (( $onekey eq "solarispackagename" ) ||
				   ( $onekey eq "solarisrequires" ) ||
				   ( $onekey eq "packagename" ) ||
				   ( $onekey eq "linuxreplaces" ) ||
                   ( $onekey eq "provides" ) ||
				   ( $onekey eq "requires" )) { $locallang =~ s/_/-/g; } # avoiding illegal package abbreviation
				$onepackage->{$onekey} =~ s/\%LANGUAGESTRING/$locallang/g;
			}
			
			# Saving the language for the package
			my $lang = $onelanguage;
			$lang =~ s/_/-/g;
			$onepackage->{'specificlanguage'} = $lang;
			
			push(@{$packages}, $onepackage);
			$foundgid = 1;
			last;
		}
	}
	
	if ( ! $foundgid )
	{
		installer::exiter::exit_program("ERROR: Could not find package info for module $gid in file \"$filename\"!", "get_packinfo");
	}	
}

#####################################################################
# Collecting all packages from scp project.
#####################################################################

sub collectpackages
{
	my ( $allmodules, $languagesarrayref ) = @_;

	installer::logger::include_header_into_logfile("Collecting packages:");
	
	my @packages = ();
	my %gid_analyzed = ();

	my $onemodule;
	foreach $onemodule ( @{$allmodules} )
	{
		my $packageinfo = "PackageInfo";
		if (( $installer::globals::tab ) && ( $onemodule->{"TabPackageInfo"} )) { $packageinfo = "TabPackageInfo" }
	
		if ( $onemodule->{$packageinfo} )	# this is a package module!
		{
			my $modulegid = $onemodule->{'gid'};
			
			# Only collecting modules with correct language for language packs
#			if ( $installer::globals::languagepack ) { if ( ! ( $modulegid =~ /_$onelanguage\s*$/ )) { next; } }
			# Resetting language, if this is no language pack
#			if ( ! $installer::globals::languagepack ) { $onelanguage = ""; }

			my $styles = "";
			if ( $onemodule->{'Styles'} ) { $styles = $onemodule->{'Styles'}; }

			# checking modules with style LANGUAGEMODULE
			my $islanguagemodule = 0;
			my $onelanguage = "";
			if ( $styles =~ /\bLANGUAGEMODULE\b/ )
			{
				$islanguagemodule = 1;
				$onelanguage = $onemodule->{'Language'}; # already checked, that it is set.
				$onelanguage =~ s/-/_/g; # pt-BR -> pt_BR in scp		
			}

			# Modules in different languages are listed more than once in multilingual installation sets
			if ( exists($gid_analyzed{$modulegid}) ) { next; }
			$gid_analyzed{$modulegid} = 1;

			my $packinfofile = $onemodule->{$packageinfo};
			
			# The file with package information has to be found in path list
			my $fileref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$packinfofile, "" , 0);

			if ( $$fileref eq "" ) { installer::exiter::exit_program("ERROR: Could not find file $packinfofile for module $modulegid!", "collectpackages"); }

			$installer::logger::Lang->printf("%s: Using packinfo: \"%s\"!\n", $modulegid, $$fileref);

			get_packinfo($modulegid, $$fileref, \@packages, $onelanguage, $islanguagemodule);
		}
	}
	
	return \@packages;
}

#####################################################################
# Printing packages content for debugging purposes
#####################################################################

sub log_packages_content
{
	my ($packages) = @_;
	
	if ( ! ( $#{$packages} > -1 )) { installer::exiter::exit_program("ERROR: No packages defined!", "print_content"); }

	installer::logger::include_header_into_logfile("Logging packages content:");

	my $infoline = "";

	for ( my $i = 0; $i <= $#{$packages}; $i++ )
	{
		my $onepackage = ${$packages}[$i];

		# checking all items that must be defined

        $installer::logger::Lang->printf("Package %s\n", $onepackage->{'module'});

		my $key;
		foreach $key (sort keys %{$onepackage})
		{
			if ( $key =~ /^\s*\;/ ) { next; }
			
			if ( $key eq "allmodules" )
			{
                $installer::logger::Lang->printf("\t%s:\n", $key);
				my $onemodule;
				foreach $onemodule ( @{$onepackage->{$key}} )
				{
                    $installer::logger::Lang->printf("\t\t%s\n", $onemodule);
				}
			}
			else
			{
                $installer::logger::Lang->printf("\t%s: %s\n", $key, $onepackage->{$key});
			}
		}

        $installer::logger::Lang->printf("\n");

	}
}

#####################################################################
# Creating assignments from modules to destination pathes.
# This is required for logging in fileinfo file. Otherwise
# the complete destination file would not be known in file list.
# Saved in %installer::globals::moduledestination
#####################################################################

sub create_module_destination_hash
{
	my ($packages, $allvariables) = @_;

	for ( my $i = 0; $i <= $#{$packages}; $i++ )
	{
		my $onepackage = ${$packages}[$i];
		
		my $defaultdestination = $onepackage->{'destpath'};
		resolve_packagevariables(\$defaultdestination, $allvariables, 1);
		if ( $^O =~ /darwin/i ) { $defaultdestination =~ s/\/opt\//\/Applications\//; }

		foreach my $onemodule ( @{$onepackage->{'allmodules'}} )
		{
			$installer::globals::moduledestination{$onemodule} = $defaultdestination;
		}
	}
}

#####################################################################
# Adding the default pathes into the files collector for Unixes.
# This is necessary to know the complete destination path in
# fileinfo log file.
#####################################################################

sub add_defaultpathes_into_filescollector
{
	my ($allfiles) = @_;
	
	for ( my $i = 0; $i <= $#{$allfiles}; $i++ )
	{
		my $onefile = ${$allfiles}[$i];
		
		if ( ! $onefile->{'destination'} ) { installer::exiter::exit_program("ERROR: No destination found at file $onefile->{'gid'}!", "add_defaultpathes_into_filescollector"); }
		my $destination = $onefile->{'destination'};

		if ( ! $onefile->{'modules'} ) { installer::exiter::exit_program("ERROR: No modules found at file $onefile->{'gid'}!", "add_defaultpathes_into_filescollector"); }
		my $module = $onefile->{'modules'};
		# If modules contains a list of modules, only taking the first one.
		if ( $module =~ /^\s*(.*?)\,/ ) { $module = $1; }
		
		if ( ! exists($installer::globals::moduledestination{$module}) ) { installer::exiter::exit_program("ERROR: No default destination path found for module $module!", "add_defaultpathes_into_filescollector"); }
		my $defaultpath = $installer::globals::moduledestination{$module};
		$defaultpath =~ s/\/\s*$//; # removing ending slashes
		my $fulldestpath = $defaultpath . $installer::globals::separator . $destination;
	
		$onefile->{'fulldestpath'} = $fulldestpath;	
	}
}

#####################################################################
# Creating list of cabinet files from packages
#####################################################################

sub prepare_cabinet_files
{
	my ($packages, $allvariables) = @_;
	
	if ( ! ( $#{$packages} > -1 )) { installer::exiter::exit_program("ERROR: No packages defined!", "print_content"); }

	installer::logger::include_header_into_logfile("Preparing cabinet files:");

	my $infoline = "";

	for ( my $i = 0; $i <= $#{$packages}; $i++ )
	{
		my $onepackage = ${$packages}[$i];
		
		my $cabinetfile = "$onepackage->{'packagename'}\.cab";
		
		resolve_packagevariables(\$cabinetfile, $allvariables, 0);
			
		$installer::globals::allcabinets{$cabinetfile} = 1;

		# checking all items that must be defined

        $installer::logger::Lang->printf("Package %s\n", $onepackage->{'module'});

		# Assigning the cab file to the module and also to all corresponding sub modules

		my $onemodule;
		foreach $onemodule ( @{$onepackage->{'allmodules'}} )
		{
			if ( ! exists($installer::globals::allcabinetassigns{$onemodule}) )
			{
				$installer::globals::allcabinetassigns{$onemodule} = $cabinetfile;
			}
			else
			{
                $installer::logger::Lang->printf("Warning: Already existing assignment: %s : %s\n",
                    $onemodule,
                    $installer::globals::allcabinetassigns{$onemodule});
                $installer::logger::Lang->printf("Ignoring further assignment: %s : %s\n",
                    $onemodule,
                    $cabinetfile);
			}
		}
	}
}

#####################################################################
# Logging assignments of cabinet files
#####################################################################

sub log_cabinet_assignments
{
	installer::logger::include_header_into_logfile("Logging cabinet files:");

    $installer::logger::Lang->printf("List of cabinet files:\n");

	my $key;
	foreach $key ( sort keys %installer::globals::allcabinets )
    {
        $installer::logger::Lang->printf("\t%s\n", $key);
    }

    $installer::logger::Lang->printf("\n");
    $installer::logger::Lang->printf("List of assignments from modules to cabinet files:\n");
	
	foreach $key ( sort keys %installer::globals::allcabinetassigns )
    {
        $installer::logger::Lang->printf("\t%s : %s\n",
            $key,
            $installer::globals::allcabinetassigns{$key});
    }
}

1;
