+check_perl_version();
+
+check_users();
+
+my %Missing_By_Type = ();
+foreach my $type (sort grep $args{$_}, keys %args) {
+ next unless ($type =~ /^with-(.*?)$/) and $deps{$1};
+
+ $type = $1;
+ section("$type dependencies");
+
+ my @missing;
+ my @deps = @{ $deps{$type} };
+
+ my %missing = test_deps(@deps);
+
+ if ( $args{'install'} ) {
+ for my $module (keys %missing) {
+ resolve_dep($module, $missing{$module}{version});
+ my $m = $module . '.pm';
+ $m =~ s!::!/!g;
+ if ( delete $INC{$m} ) {
+ my $symtab = $module . '::';
+ no strict 'refs';
+ for my $symbol ( keys %{$symtab} ) {
+ next if substr( $symbol, -2, 2 ) eq '::';
+ delete $symtab->{$symbol};
+ }
+ }
+ delete $missing{$module}
+ if test_dep($module, $missing{$module}{version}, $AVOID{$module});
+ }
+ }
+
+ $Missing_By_Type{$type} = \%missing if keys %missing;
+}
+
+if ( $args{'install'} && keys %Missing_By_Type ) {
+ exec($0, @orig_argv, '--no-install');
+}
+else {
+ conclude(%Missing_By_Type);
+}
+
+sub test_deps {
+ my @deps = @_;
+
+ my %missing;
+ while(@deps) {
+ my $module = shift @deps;
+ my $version = shift @deps;
+ my($test, $error) = test_dep($module, $version, $AVOID{$module});
+ my $msg = $module . ($version && !$error ? " >= $version" : '');
+ print_found($msg, $test, $error);
+
+ $missing{$module} = { version => $version, error => $error } unless $test;
+ }
+
+ return %missing;
+}
+
+sub test_dep {
+ my $module = shift;
+ my $version = shift;
+ my $avoid = shift;
+
+ if ( $args{'list-deps'} ) {
+ print $module, ': ', $version || 0, "\n";
+ }
+ else {
+ eval "use $module $version ()";
+ if ( my $error = $@ ) {
+ return 0 unless wantarray;
+
+ $error =~ s/\n(.*)$//s;
+ $error =~ s/at \(eval \d+\) line \d+\.$//;
+ undef $error if $error =~ /this is only/;
+
+ return ( 0, $error );
+ }
+
+ if ( $avoid ) {
+ my $version = $module->VERSION;
+ if ( grep $version eq $_, @$avoid ) {
+ return 0 unless wantarray;
+ return (0, "It's known that there are problems with RT and version '$version' of '$module' module. If it's the latest available version of the module then you have to downgrade manually.");
+ }
+ }
+
+ return 1;
+ }
+}
+
+sub resolve_dep {
+ my $module = shift;
+ my $version = shift;
+
+ print "\nInstall module $module\n";
+
+ my $ext = $ENV{'RT_FIX_DEPS_CMD'} || $ENV{'PERL_PREFER_CPAN_CLIENT'};
+ unless( $ext ) {
+ my $configured = 1;
+ {
+ local @INC = @INC;
+ if ( $ENV{'HOME'} ) {
+ unshift @INC, "$ENV{'HOME'}/.cpan";
+ }
+ $configured = eval { require CPAN::MyConfig } || eval { require CPAN::Config };
+ }
+ unless ( $configured ) {
+ print <<END;
+You haven't configured the CPAN shell yet.
+Please run `@PERL@ -MCPAN -e shell` to configure it.
+END
+ exit(1);
+ }
+ my $rv = eval { require CPAN; CPAN::Shell->install($module) };
+ return $rv unless $@;
+
+ print <<END;
+Failed to load module CPAN.
+
+-------- Error ---------
+$@
+------------------------
+
+When we tried to start installing RT's perl dependencies,
+we were unable to load the CPAN client. This module is usually distributed
+with Perl. This usually indicates that your vendor has shipped an unconfigured
+or incorrectly configured CPAN client.
+The error above may (or may not) give you a hint about what went wrong
+
+You have several choices about how to install dependencies in
+this situatation:
+
+1) use a different tool to install dependencies by running setting the following
+ shell environment variable and rerunning this tool:
+ RT_FIX_DEPS_CMD='@PERL@ -MCPAN -e"install %s"'
+2) Attempt to configure CPAN by running:
+ `@PERL@ -MCPAN -e shell` program from shell.
+ If this fails, you may have to manually upgrade CPAN (see below)
+3) Try to update the CPAN client. Download it from:
+ http://search.cpan.org/dist/CPAN and try again
+4) Install each dependency manually by downloading them one by one from
+ http://search.cpan.org
+
+END
+ exit(1);
+ }
+
+ if( $ext =~ /\%s/) {
+ $ext =~ s/\%s/$module/g; # sprintf( $ext, $module );
+ } else {
+ $ext .= " $module";
+ }
+ print "\t\tcommand: '$ext'\n";
+ return scalar `$ext 1>&2`;
+}
+
+sub download_mods {
+ my %modules;
+ use CPAN;
+