[Bps-public-commit] rtfm-extension-articletemplate branch, master, updated. 7b54eeb4b012079e8169f2a3c9d75002b5e15435

Kevin Falcone falcone at bestpractical.com
Wed Nov 4 10:49:10 EST 2009


The branch, master has been updated
  discards  5660f4aece4834ac22db1644792f4a019747e993 (commit)
       via  7b54eeb4b012079e8169f2a3c9d75002b5e15435 (commit)
       via  465eb1d93dff7f78fb1d6fa2e088f96648565421 (commit)
       via  30d635866e22ef948532526907f222891d6b1848 (commit)
       via  5b7406838bb7a2e3bdb1701f0bc9d48662b84151 (commit)
       via  e411488a049e9710e138413e126a66c8b2034357 (commit)
       via  40c82616ab6a1a77451ef01b0a6ea432552f9592 (commit)
       via  248f916baf239092ea4c18dc7d8f2792ffd869c1 (commit)
       via  c20d57e4fdba420d3ccfdad1e22a27d1c3203a9f (commit)
       via  e72bde78b77c1521136f7ce495212e23b3acbfea (commit)
       via  8899c3237d577c3c20bdcbf20fbcc974f461606a (commit)
       via  7f759a34204eccf0245577a80eac818e693e919e (commit)

This update added new revisions after undoing existing revisions.  That is
to say, the old revision is not a strict subset of the new revision.  This
situation occurs when you --force push a change and generate a repository
containing something like this:

 * -- * -- B -- O -- O -- O (5660f4aece4834ac22db1644792f4a019747e993)
            \
             N -- N -- N (7b54eeb4b012079e8169f2a3c9d75002b5e15435)

When this happens we assume that you've already had alert emails for all
of the O revisions, and so we here report only the revisions in the N
branch from the common base, B.

Summary of changes:
 Changes                                            |   10 +
 MANIFEST                                           |   23 +
 META.yml                                           |   24 +
 Makefile.PL                                        |   19 +
 README                                             |    1 +
 .../Article/Elements/Preformatted/ProcessContent   |   30 +
 inc/Module/AutoInstall.pm                          |  768 ++++++++++++++++++++
 inc/Module/Install.pm                              |  313 ++++++++
 inc/Module/Install/AutoInstall.pm                  |   61 ++
 inc/Module/Install/Base.pm                         |   70 ++
 inc/Module/Install/Can.pm                          |   82 +++
 inc/Module/Install/Fetch.pm                        |   93 +++
 inc/Module/Install/Include.pm                      |   34 +
 inc/Module/Install/Makefile.pm                     |  245 +++++++
 inc/Module/Install/Metadata.pm                     |  318 ++++++++
 inc/Module/Install/RTx.pm                          |  191 +++++
 inc/Module/Install/Win32.pm                        |   64 ++
 inc/Module/Install/WriteAll.pm                     |   40 +
 lib/RT/FM/Article_Local.pm                         |   81 ++
 lib/RTFM/Extension/ArticleTemplates.pm             |   56 ++
 t/00.load.t                                        |    7 +
 t/pod-coverage.t                                   |    6 +
 t/pod.t                                            |    6 +
 23 files changed, 2542 insertions(+), 0 deletions(-)
 delete mode 100644 .gitignore
 create mode 100644 Changes
 create mode 100644 MANIFEST
 create mode 100644 META.yml
 create mode 100644 Makefile.PL
 create mode 100644 README
 create mode 100644 html/Callbacks/RTFM-Extension-ArticleTemplates/RTFM/Article/Elements/Preformatted/ProcessContent
 create mode 100644 inc/Module/AutoInstall.pm
 create mode 100644 inc/Module/Install.pm
 create mode 100644 inc/Module/Install/AutoInstall.pm
 create mode 100644 inc/Module/Install/Base.pm
 create mode 100644 inc/Module/Install/Can.pm
 create mode 100644 inc/Module/Install/Fetch.pm
 create mode 100644 inc/Module/Install/Include.pm
 create mode 100644 inc/Module/Install/Makefile.pm
 create mode 100644 inc/Module/Install/Metadata.pm
 create mode 100644 inc/Module/Install/RTx.pm
 create mode 100644 inc/Module/Install/Win32.pm
 create mode 100644 inc/Module/Install/WriteAll.pm
 create mode 100644 lib/RT/FM/Article_Local.pm
 create mode 100644 lib/RTFM/Extension/ArticleTemplates.pm
 create mode 100644 t/00.load.t
 create mode 100644 t/pod-coverage.t
 create mode 100644 t/pod.t

- Log -----------------------------------------------------------------
commit 7f759a34204eccf0245577a80eac818e693e919e
Author: Kevin Falcone <falcone at bestpractical.com>
Date:   Fri May 9 20:38:37 2008 +0000

    Directory for svk import.

commit 8899c3237d577c3c20bdcbf20fbcc974f461606a
Author: Kevin Falcone <falcone at bestpractical.com>
Date:   Fri May 9 20:38:59 2008 +0000

    initial import

diff --git a/.cvsignore b/.cvsignore
new file mode 100644
index 0000000..6c579e6
--- /dev/null
+++ b/.cvsignore
@@ -0,0 +1,10 @@
+blib*
+Makefile
+Makefile.old
+Build
+_build*
+pm_to_blib*
+*.tar.gz
+.lwpcookies
+RTFM-Extension-ArticleTemplates-*
+cover_db
diff --git a/Changes b/Changes
new file mode 100644
index 0000000..785f2d1
--- /dev/null
+++ b/Changes
@@ -0,0 +1,5 @@
+Revision history for RTFM-Extension-ArticleTemplates
+
+0.01  Fri May  9 14:51:44 2008
+       Initial release.
+
diff --git a/MANIFEST b/MANIFEST
new file mode 100644
index 0000000..7785679
--- /dev/null
+++ b/MANIFEST
@@ -0,0 +1,8 @@
+Changes
+MANIFEST
+Makefile.PL
+README
+lib/RTFM/Extension/ArticleTemplates.pm
+t/00.load.t
+t/pod-coverage.t
+t/pod.t
diff --git a/Makefile.PL b/Makefile.PL
new file mode 100644
index 0000000..17aedd0
--- /dev/null
+++ b/Makefile.PL
@@ -0,0 +1,14 @@
+use inc::Module::Install;
+
+RTx 'RTFM-Extension-ArticleTemplates';
+license 'GPL Version 2';
+all_from 'lib/RTFM/Extension/ArticleTemplates.pm';
+author   'Kevin Falcone <falcone at bestpractical.com>';
+
+build_requires 'Test::More';
+requires('RT::FM' => 2.2.2);
+
+auto_install;
+
+WriteAll;
+
diff --git a/README b/README
new file mode 100644
index 0000000..d34d794
--- /dev/null
+++ b/README
@@ -0,0 +1,39 @@
+RTFM-Extension-ArticleTemplates version 0.0.1
+
+[ REPLACE THIS...
+
+  The README is used to introduce the module and provide instructions on
+  how to install the module, any machine dependencies it may have (for
+  example C compilers and installed libraries) and any other information
+  that should be understood before the module is installed.
+
+  A README file is required for CPAN modules since CPAN extracts the
+  README file from a module distribution so that people browsing the
+  archive can use it get an idea of the modules uses. It is usually a
+  good idea to provide version information here so that people can
+  decide whether fixes for the module are worth downloading.
+]
+
+
+INSTALLATION
+
+To install this module, run the following commands:
+
+	perl Makefile.PL
+	make
+	make test
+	make install
+
+
+DEPENDENCIES
+
+None.
+
+
+COPYRIGHT AND LICENCE
+
+Copyright (C) 2008, Best Practical Solutions LLC.
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
diff --git a/html/Callbacks/RTFM-Extension-ArticleTemplates/RTFM/Article/Elements/Preformatted/ProcessContent b/html/Callbacks/RTFM-Extension-ArticleTemplates/RTFM/Article/Elements/Preformatted/ProcessContent
new file mode 100644
index 0000000..9b9606b
--- /dev/null
+++ b/html/Callbacks/RTFM-Extension-ArticleTemplates/RTFM/Article/Elements/Preformatted/ProcessContent
@@ -0,0 +1,30 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%#  Copyright (c) 2002-2003 Jesse Vincent <jesse at bestpractical.com>
+%#  
+%#  This program is free software; you can redistribute it and/or modify
+%#  it under the terms of version 2 of the GNU General Public License 
+%#  as published by the Free Software Foundation.
+%# 
+%#  A copy of that license should have arrived with this
+%#  software, but in any event can be snarfed from www.gnu.org.
+%# 
+%#  This program is distributed in the hope that it will be useful,
+%#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+%#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+%#  GNU General Public License for more details.
+%# 
+%# END LICENSE BLOCK
+<%init>
+my ($new, $msg) = $Article->ParseTemplate( $content, Ticket => $Ticket );
+unless ( defined $new && length $new ) {
+    $RT::Logger->error("Couldn't parse article's content: $msg");
+} else {
+    $content = $new;
+}
+</%init>
+<%args>
+$Article
+$Ticket => undef
+$content 
+</%args>
diff --git a/inc/Module/Install.pm b/inc/Module/Install.pm
new file mode 100644
index 0000000..052cf1e
--- /dev/null
+++ b/inc/Module/Install.pm
@@ -0,0 +1,353 @@
+#line 1
+package Module::Install;
+
+# For any maintainers:
+# The load order for Module::Install is a bit magic.
+# It goes something like this...
+#
+# IF ( host has Module::Install installed, creating author mode ) {
+#     1. Makefile.PL calls "use inc::Module::Install"
+#     2. $INC{inc/Module/Install.pm} set to installed version of inc::Module::Install
+#     3. The installed version of inc::Module::Install loads
+#     4. inc::Module::Install calls "require Module::Install"
+#     5. The ./inc/ version of Module::Install loads
+# } ELSE {
+#     1. Makefile.PL calls "use inc::Module::Install"
+#     2. $INC{inc/Module/Install.pm} set to ./inc/ version of Module::Install
+#     3. The ./inc/ version of Module::Install loads
+# }
+
+BEGIN {
+	require 5.004;
+}
+use strict 'vars';
+
+use vars qw{$VERSION};
+BEGIN {
+	# All Module::Install core packages now require synchronised versions.
+	# This will be used to ensure we don't accidentally load old or
+	# different versions of modules.
+	# This is not enforced yet, but will be some time in the next few
+	# releases once we can make sure it won't clash with custom
+	# Module::Install extensions.
+	$VERSION = '0.72';
+
+	*inc::Module::Install::VERSION = *VERSION;
+	@inc::Module::Install::ISA     = __PACKAGE__;
+
+}
+
+
+
+
+
+# Whether or not inc::Module::Install is actually loaded, the
+# $INC{inc/Module/Install.pm} is what will still get set as long as
+# the caller loaded module this in the documented manner.
+# If not set, the caller may NOT have loaded the bundled version, and thus
+# they may not have a MI version that works with the Makefile.PL. This would
+# result in false errors or unexpected behaviour. And we don't want that.
+my $file = join( '/', 'inc', split /::/, __PACKAGE__ ) . '.pm';
+unless ( $INC{$file} ) { die <<"END_DIE" }
+
+Please invoke ${\__PACKAGE__} with:
+
+	use inc::${\__PACKAGE__};
+
+not:
+
+	use ${\__PACKAGE__};
+
+END_DIE
+
+
+
+
+
+# If the script that is loading Module::Install is from the future,
+# then make will detect this and cause it to re-run over and over
+# again. This is bad. Rather than taking action to touch it (which
+# is unreliable on some platforms and requires write permissions)
+# for now we should catch this and refuse to run.
+if ( -f $0 and (stat($0))[9] > time ) { die <<"END_DIE" }
+
+Your installer $0 has a modification time in the future.
+
+This is known to create infinite loops in make.
+
+Please correct this, then run $0 again.
+
+END_DIE
+
+
+
+
+
+# Build.PL was formerly supported, but no longer is due to excessive
+# difficulty in implementing every single feature twice.
+if ( $0 =~ /Build.PL$/i or -f 'Build.PL' ) { die <<"END_DIE" }
+
+Module::Install no longer supports Build.PL.
+
+It was impossible to maintain duel backends, and has been deprecated.
+
+Please remove all Build.PL files and only use the Makefile.PL installer.
+
+END_DIE
+
+
+
+
+
+# To save some more typing in Module::Install installers, every...
+# use inc::Module::Install
+# ...also acts as an implicit use strict.
+$^H |= strict::bits(qw(refs subs vars));
+
+
+
+
+
+use Cwd        ();
+use File::Find ();
+use File::Path ();
+use FindBin;
+
+sub autoload {
+	my $self = shift;
+	my $who  = $self->_caller;
+	my $cwd  = Cwd::cwd();
+	my $sym  = "${who}::AUTOLOAD";
+	$sym->{$cwd} = sub {
+		my $pwd = Cwd::cwd();
+		if ( my $code = $sym->{$pwd} ) {
+			# delegate back to parent dirs
+			goto &$code unless $cwd eq $pwd;
+		}
+		$$sym =~ /([^:]+)$/ or die "Cannot autoload $who - $sym";
+		unshift @_, ( $self, $1 );
+		goto &{$self->can('call')} unless uc($1) eq $1;
+	};
+}
+
+sub import {
+	my $class = shift;
+	my $self  = $class->new(@_);
+	my $who   = $self->_caller;
+
+	unless ( -f $self->{file} ) {
+		require "$self->{path}/$self->{dispatch}.pm";
+		File::Path::mkpath("$self->{prefix}/$self->{author}");
+		$self->{admin} = "$self->{name}::$self->{dispatch}"->new( _top => $self );
+		$self->{admin}->init;
+		@_ = ($class, _self => $self);
+		goto &{"$self->{name}::import"};
+	}
+
+	*{"${who}::AUTOLOAD"} = $self->autoload;
+	$self->preload;
+
+	# Unregister loader and worker packages so subdirs can use them again
+	delete $INC{"$self->{file}"};
+	delete $INC{"$self->{path}.pm"};
+
+	return 1;
+}
+
+sub preload {
+	my $self = shift;
+	unless ( $self->{extensions} ) {
+		$self->load_extensions(
+			"$self->{prefix}/$self->{path}", $self
+		);
+	}
+
+	my @exts = @{$self->{extensions}};
+	unless ( @exts ) {
+		my $admin = $self->{admin};
+		@exts = $admin->load_all_extensions;
+	}
+
+	my %seen;
+	foreach my $obj ( @exts ) {
+		while (my ($method, $glob) = each %{ref($obj) . '::'}) {
+			next unless $obj->can($method);
+			next if $method =~ /^_/;
+			next if $method eq uc($method);
+			$seen{$method}++;
+		}
+	}
+
+	my $who = $self->_caller;
+	foreach my $name ( sort keys %seen ) {
+		*{"${who}::$name"} = sub {
+			${"${who}::AUTOLOAD"} = "${who}::$name";
+			goto &{"${who}::AUTOLOAD"};
+		};
+	}
+}
+
+sub new {
+	my ($class, %args) = @_;
+
+	# ignore the prefix on extension modules built from top level.
+	my $base_path = Cwd::abs_path($FindBin::Bin);
+	unless ( Cwd::abs_path(Cwd::cwd()) eq $base_path ) {
+		delete $args{prefix};
+	}
+
+	return $args{_self} if $args{_self};
+
+	$args{dispatch} ||= 'Admin';
+	$args{prefix}   ||= 'inc';
+	$args{author}   ||= ($^O eq 'VMS' ? '_author' : '.author');
+	$args{bundle}   ||= 'inc/BUNDLES';
+	$args{base}     ||= $base_path;
+	$class =~ s/^\Q$args{prefix}\E:://;
+	$args{name}     ||= $class;
+	$args{version}  ||= $class->VERSION;
+	unless ( $args{path} ) {
+		$args{path}  = $args{name};
+		$args{path}  =~ s!::!/!g;
+	}
+	$args{file}     ||= "$args{base}/$args{prefix}/$args{path}.pm";
+	$args{wrote}      = 0;
+
+	bless( \%args, $class );
+}
+
+sub call {
+	my ($self, $method) = @_;
+	my $obj = $self->load($method) or return;
+        splice(@_, 0, 2, $obj);
+	goto &{$obj->can($method)};
+}
+
+sub load {
+	my ($self, $method) = @_;
+
+	$self->load_extensions(
+		"$self->{prefix}/$self->{path}", $self
+	) unless $self->{extensions};
+
+	foreach my $obj (@{$self->{extensions}}) {
+		return $obj if $obj->can($method);
+	}
+
+	my $admin = $self->{admin} or die <<"END_DIE";
+The '$method' method does not exist in the '$self->{prefix}' path!
+Please remove the '$self->{prefix}' directory and run $0 again to load it.
+END_DIE
+
+	my $obj = $admin->load($method, 1);
+	push @{$self->{extensions}}, $obj;
+
+	$obj;
+}
+
+sub load_extensions {
+	my ($self, $path, $top) = @_;
+
+	unless ( grep { lc $_ eq lc $self->{prefix} } @INC ) {
+		unshift @INC, $self->{prefix};
+	}
+
+	foreach my $rv ( $self->find_extensions($path) ) {
+		my ($file, $pkg) = @{$rv};
+		next if $self->{pathnames}{$pkg};
+
+		local $@;
+		my $new = eval { require $file; $pkg->can('new') };
+		unless ( $new ) {
+			warn $@ if $@;
+			next;
+		}
+		$self->{pathnames}{$pkg} = delete $INC{$file};
+		push @{$self->{extensions}}, &{$new}($pkg, _top => $top );
+	}
+
+	$self->{extensions} ||= [];
+}
+
+sub find_extensions {
+	my ($self, $path) = @_;
+
+	my @found;
+	File::Find::find( sub {
+		my $file = $File::Find::name;
+		return unless $file =~ m!^\Q$path\E/(.+)\.pm\Z!is;
+		my $subpath = $1;
+		return if lc($subpath) eq lc($self->{dispatch});
+
+		$file = "$self->{path}/$subpath.pm";
+		my $pkg = "$self->{name}::$subpath";
+		$pkg =~ s!/!::!g;
+
+		# If we have a mixed-case package name, assume case has been preserved
+		# correctly.  Otherwise, root through the file to locate the case-preserved
+		# version of the package name.
+		if ( $subpath eq lc($subpath) || $subpath eq uc($subpath) ) {
+			my $content = Module::Install::_read($subpath . '.pm');
+			my $in_pod  = 0;
+			foreach ( split //, $content ) {
+				$in_pod = 1 if /^=\w/;
+				$in_pod = 0 if /^=cut/;
+				next if ($in_pod || /^=cut/);  # skip pod text
+				next if /^\s*#/;               # and comments
+				if ( m/^\s*package\s+($pkg)\s*;/i ) {
+					$pkg = $1;
+					last;
+				}
+			}
+		}
+
+		push @found, [ $file, $pkg ];
+	}, $path ) if -d $path;
+
+	@found;
+}
+
+
+
+
+
+#####################################################################
+# Utility Functions
+
+sub _caller {
+	my $depth = 0;
+	my $call  = caller($depth);
+	while ( $call eq __PACKAGE__ ) {
+		$depth++;
+		$call = caller($depth);
+	}
+	return $call;
+}
+
+sub _read {
+	local *FH;
+	open FH, "< $_[0]" or die "open($_[0]): $!";
+	my $str = do { local $/; <FH> };
+	close FH or die "close($_[0]): $!";
+	return $str;
+}
+
+sub _write {
+	local *FH;
+	open FH, "> $_[0]" or die "open($_[0]): $!";
+	foreach ( 1 .. $#_ ) { print FH $_[$_] or die "print($_[0]): $!" }
+	close FH or die "close($_[0]): $!";
+}
+
+sub _version {
+	my $s = shift || 0;
+	   $s =~ s/^(\d+)\.?//;
+	my $l = $1 || 0;
+	my @v = map { $_ . '0' x (3 - length $_) } $s =~ /(\d{1,3})\D?/g;
+	   $l = $l . '.' . join '', @v if @v;
+	return $l + 0;
+}
+
+1;
+
+# Copyright 2008 Adam Kennedy.
diff --git a/inc/Module/Install/Base.pm b/inc/Module/Install/Base.pm
new file mode 100644
index 0000000..7fd0189
--- /dev/null
+++ b/inc/Module/Install/Base.pm
@@ -0,0 +1,70 @@
+#line 1
+package Module::Install::Base;
+
+$VERSION = '0.72';
+
+# Suspend handler for "redefined" warnings
+BEGIN {
+	my $w = $SIG{__WARN__};
+	$SIG{__WARN__} = sub { $w };
+}
+
+### This is the ONLY module that shouldn't have strict on
+# use strict;
+
+#line 41
+
+sub new {
+    my ($class, %args) = @_;
+
+    foreach my $method ( qw(call load) ) {
+        *{"$class\::$method"} = sub {
+            shift()->_top->$method(@_);
+        } unless defined &{"$class\::$method"};
+    }
+
+    bless( \%args, $class );
+}
+
+#line 61
+
+sub AUTOLOAD {
+    my $self = shift;
+    local $@;
+    my $autoload = eval { $self->_top->autoload } or return;
+    goto &$autoload;
+}
+
+#line 76
+
+sub _top { $_[0]->{_top} }
+
+#line 89
+
+sub admin {
+    $_[0]->_top->{admin} or Module::Install::Base::FakeAdmin->new;
+}
+
+sub is_admin {
+    $_[0]->admin->VERSION;
+}
+
+sub DESTROY {}
+
+package Module::Install::Base::FakeAdmin;
+
+my $Fake;
+sub new { $Fake ||= bless(\@_, $_[0]) }
+
+sub AUTOLOAD {}
+
+sub DESTROY {}
+
+# Restore warning handler
+BEGIN {
+	$SIG{__WARN__} = $SIG{__WARN__}->();
+}
+
+1;
+
+#line 138
diff --git a/inc/Module/Install/Makefile.pm b/inc/Module/Install/Makefile.pm
new file mode 100644
index 0000000..f40a97c
--- /dev/null
+++ b/inc/Module/Install/Makefile.pm
@@ -0,0 +1,245 @@
+#line 1
+package Module::Install::Makefile;
+
+use strict 'vars';
+use Module::Install::Base;
+use ExtUtils::MakeMaker ();
+
+use vars qw{$VERSION $ISCORE @ISA};
+BEGIN {
+	$VERSION = '0.72';
+	$ISCORE  = 1;
+	@ISA     = qw{Module::Install::Base};
+}
+
+sub Makefile { $_[0] }
+
+my %seen = ();
+
+sub prompt {
+	shift;
+
+	# Infinite loop protection
+	my @c = caller();
+	if ( ++$seen{"$c[1]|$c[2]|$_[0]"} > 3 ) {
+		die "Caught an potential prompt infinite loop ($c[1]|$c[2]|$_[0])";
+	}
+
+	# In automated testing, always use defaults
+	if ( $ENV{AUTOMATED_TESTING} and ! $ENV{PERL_MM_USE_DEFAULT} ) {
+		local $ENV{PERL_MM_USE_DEFAULT} = 1;
+		goto &ExtUtils::MakeMaker::prompt;
+	} else {
+		goto &ExtUtils::MakeMaker::prompt;
+	}
+}
+
+sub makemaker_args {
+	my $self = shift;
+	my $args = ($self->{makemaker_args} ||= {});
+	  %$args = ( %$args, @_ ) if @_;
+	$args;
+}
+
+# For mm args that take multiple space-seperated args,
+# append an argument to the current list.
+sub makemaker_append {
+	my $self = sShift;
+	my $name = shift;
+	my $args = $self->makemaker_args;
+	$args->{name} = defined $args->{$name}
+		? join( ' ', $args->{name}, @_ )
+		: join( ' ', @_ );
+}
+
+sub build_subdirs {
+	my $self    = shift;
+	my $subdirs = $self->makemaker_args->{DIR} ||= [];
+	for my $subdir (@_) {
+		push @$subdirs, $subdir;
+	}
+}
+
+sub clean_files {
+	my $self  = shift;
+	my $clean = $self->makemaker_args->{clean} ||= {};
+	  %$clean = (
+		%$clean, 
+		FILES => join ' ', grep { length $_ } ($clean->{FILES} || (), @_),
+	);
+}
+
+sub realclean_files {
+	my $self      = shift;
+	my $realclean = $self->makemaker_args->{realclean} ||= {};
+	  %$realclean = (
+		%$realclean, 
+		FILES => join ' ', grep { length $_ } ($realclean->{FILES} || (), @_),
+	);
+}
+
+sub libs {
+	my $self = shift;
+	my $libs = ref $_[0] ? shift : [ shift ];
+	$self->makemaker_args( LIBS => $libs );
+}
+
+sub inc {
+	my $self = shift;
+	$self->makemaker_args( INC => shift );
+}
+
+my %test_dir = ();
+
+sub _wanted_t {
+	/\.t$/ and -f $_ and $test_dir{$File::Find::dir} = 1;
+}
+
+sub tests_recursive {
+	my $self = shift;
+	if ( $self->tests ) {
+		die "tests_recursive will not work if tests are already defined";
+	}
+	my $dir = shift || 't';
+	unless ( -d $dir ) {
+		die "tests_recursive dir '$dir' does not exist";
+	}
+	%test_dir = ();
+	require File::Find;
+	File::Find::find( \&_wanted_t, $dir );
+	$self->tests( join ' ', map { "$_/*.t" } sort keys %test_dir );
+}
+
+sub write {
+	my $self = shift;
+	die "&Makefile->write() takes no arguments\n" if @_;
+
+	# Make sure we have a new enough
+	require ExtUtils::MakeMaker;
+	$self->configure_requires( 'ExtUtils::MakeMaker' => $ExtUtils::MakeMaker::VERSION );
+
+	# Generate the 
+	my $args = $self->makemaker_args;
+	$args->{DISTNAME} = $self->name;
+	$args->{NAME}     = $self->module_name || $self->name;
+	$args->{VERSION}  = $self->version;
+	$args->{NAME}     =~ s/-/::/g;
+	if ( $self->tests ) {
+		$args->{test} = { TESTS => $self->tests };
+	}
+	if ($] >= 5.005) {
+		$args->{ABSTRACT} = $self->abstract;
+		$args->{AUTHOR}   = $self->author;
+	}
+	if ( eval($ExtUtils::MakeMaker::VERSION) >= 6.10 ) {
+		$args->{NO_META} = 1;
+	}
+	if ( eval($ExtUtils::MakeMaker::VERSION) > 6.17 and $self->sign ) {
+		$args->{SIGN} = 1;
+	}
+	unless ( $self->is_admin ) {
+		delete $args->{SIGN};
+	}
+
+	# merge both kinds of requires into prereq_pm
+	my $prereq = ($args->{PREREQ_PM} ||= {});
+	%$prereq = ( %$prereq,
+		map { @$_ }
+		map { @$_ }
+		grep $_,
+		($self->configure_requires, $self->build_requires, $self->requires)
+	);
+
+	# Remove any reference to perl, PREREQ_PM doesn't support it
+	delete $args->{PREREQ_PM}->{perl};
+
+	# merge both kinds of requires into prereq_pm
+	my $subdirs = ($args->{DIR} ||= []);
+	if ($self->bundles) {
+		foreach my $bundle (@{ $self->bundles }) {
+			my ($file, $dir) = @$bundle;
+			push @$subdirs, $dir if -d $dir;
+			delete $prereq->{$file};
+		}
+	}
+
+	if ( my $perl_version = $self->perl_version ) {
+		eval "use $perl_version; 1"
+			or die "ERROR: perl: Version $] is installed, "
+			. "but we need version >= $perl_version";
+	}
+
+	$args->{INSTALLDIRS} = $self->installdirs;
+
+	my %args = map { ( $_ => $args->{$_} ) } grep {defined($args->{$_})} keys %$args;
+
+	my $user_preop = delete $args{dist}->{PREOP};
+	if (my $preop = $self->admin->preop($user_preop)) {
+		$args{dist} = $preop;
+	}
+
+	my $mm = ExtUtils::MakeMaker::WriteMakefile(%args);
+	$self->fix_up_makefile($mm->{FIRST_MAKEFILE} || 'Makefile');
+}
+
+sub fix_up_makefile {
+	my $self          = shift;
+	my $makefile_name = shift;
+	my $top_class     = ref($self->_top) || '';
+	my $top_version   = $self->_top->VERSION || '';
+
+	my $preamble = $self->preamble 
+		? "# Preamble by $top_class $top_version\n"
+			. $self->preamble
+		: '';
+	my $postamble = "# Postamble by $top_class $top_version\n"
+		. ($self->postamble || '');
+
+	local *MAKEFILE;
+	open MAKEFILE, "< $makefile_name" or die "fix_up_makefile: Couldn't open $makefile_name: $!";
+	my $makefile = do { local $/; <MAKEFILE> };
+	close MAKEFILE or die $!;
+
+	$makefile =~ s/\b(test_harness\(\$\(TEST_VERBOSE\), )/$1'inc', /;
+	$makefile =~ s/( -I\$\(INST_ARCHLIB\))/ -Iinc$1/g;
+	$makefile =~ s/( "-I\$\(INST_LIB\)")/ "-Iinc"$1/g;
+	$makefile =~ s/^(FULLPERL = .*)/$1 "-Iinc"/m;
+	$makefile =~ s/^(PERL = .*)/$1 "-Iinc"/m;
+
+	# Module::Install will never be used to build the Core Perl
+	# Sometimes PERL_LIB and PERL_ARCHLIB get written anyway, which breaks
+	# PREFIX/PERL5LIB, and thus, install_share. Blank them if they exist
+	$makefile =~ s/^PERL_LIB = .+/PERL_LIB =/m;
+	#$makefile =~ s/^PERL_ARCHLIB = .+/PERL_ARCHLIB =/m;
+
+	# Perl 5.005 mentions PERL_LIB explicitly, so we have to remove that as well.
+	$makefile =~ s/(\"?)-I\$\(PERL_LIB\)\1//g;
+
+	# XXX - This is currently unused; not sure if it breaks other MM-users
+	# $makefile =~ s/^pm_to_blib\s+:\s+/pm_to_blib :: /mg;
+
+	open  MAKEFILE, "> $makefile_name" or die "fix_up_makefile: Couldn't open $makefile_name: $!";
+	print MAKEFILE  "$preamble$makefile$postamble" or die $!;
+	close MAKEFILE  or die $!;
+
+	1;
+}
+
+sub preamble {
+	my ($self, $text) = @_;
+	$self->{preamble} = $text . $self->{preamble} if defined $text;
+	$self->{preamble};
+}
+
+sub postamble {
+	my ($self, $text) = @_;
+	$self->{postamble} ||= $self->admin->postamble;
+	$self->{postamble} .= $text if defined $text;
+	$self->{postamble}
+}
+
+1;
+
+__END__
+
+#line 371
diff --git a/inc/Module/Install/Metadata.pm b/inc/Module/Install/Metadata.pm
new file mode 100644
index 0000000..a10c773
--- /dev/null
+++ b/inc/Module/Install/Metadata.pm
@@ -0,0 +1,386 @@
+#line 1
+package Module::Install::Metadata;
+
+use strict 'vars';
+use Module::Install::Base;
+
+use vars qw{$VERSION $ISCORE @ISA};
+BEGIN {
+	$VERSION = '0.72';
+	$ISCORE  = 1;
+	@ISA     = qw{Module::Install::Base};
+}
+
+my @scalar_keys = qw{
+	name
+	module_name
+	abstract
+	author
+	version
+	license
+	distribution_type
+	perl_version
+	tests
+	installdirs
+};
+
+my @tuple_keys = qw{
+	configure_requires
+	build_requires
+	requires
+	recommends
+	bundles
+};
+
+sub Meta            { shift        }
+sub Meta_ScalarKeys { @scalar_keys }
+sub Meta_TupleKeys  { @tuple_keys  }
+
+foreach my $key (@scalar_keys) {
+	*$key = sub {
+		my $self = shift;
+		return $self->{values}{$key} if defined wantarray and !@_;
+		$self->{values}{$key} = shift;
+		return $self;
+	};
+}
+
+sub requires {
+	my $self = shift;
+	while ( @_ ) {
+		my $module  = shift or last;
+		my $version = shift || 0;
+		push @{ $self->{values}->{requires} }, [ $module, $version ];
+	}
+	$self->{values}{requires};
+}
+
+sub build_requires {
+	my $self = shift;
+	while ( @_ ) {
+		my $module  = shift or last;
+		my $version = shift || 0;
+		push @{ $self->{values}->{build_requires} }, [ $module, $version ];
+	}
+	$self->{values}{build_requires};
+}
+
+sub configure_requires {
+	my $self = shift;
+	while ( @_ ) {
+		my $module  = shift or last;
+		my $version = shift || 0;
+		push @{ $self->{values}->{configure_requires} }, [ $module, $version ];
+	}
+	$self->{values}{configure_requires};
+}
+
+sub recommends {
+	my $self = shift;
+	while ( @_ ) {
+		my $module  = shift or last;
+		my $version = shift || 0;
+		push @{ $self->{values}->{recommends} }, [ $module, $version ];
+	}
+	$self->{values}{recommends};
+}
+
+sub bundles {
+	my $self = shift;
+	while ( @_ ) {
+		my $module  = shift or last;
+		my $version = shift || 0;
+		push @{ $self->{values}->{bundles} }, [ $module, $version ];
+	}
+	$self->{values}{bundles};
+}
+
+# Aliases for build_requires that will have alternative
+# meanings in some future version of META.yml.
+sub test_requires      { shift->build_requires(@_) }
+sub install_requires   { shift->build_requires(@_) }
+
+# Aliases for installdirs options
+sub install_as_core    { $_[0]->installdirs('perl')   }
+sub install_as_cpan    { $_[0]->installdirs('site')   }
+sub install_as_site    { $_[0]->installdirs('site')   }
+sub install_as_vendor  { $_[0]->installdirs('vendor') }
+
+sub sign {
+	my $self = shift;
+	return $self->{'values'}{'sign'} if defined wantarray and ! @_;
+	$self->{'values'}{'sign'} = ( @_ ? $_[0] : 1 );
+	return $self;
+}
+
+sub dynamic_config {
+	my $self = shift;
+	unless ( @_ ) {
+		warn "You MUST provide an explicit true/false value to dynamic_config, skipping\n";
+		return $self;
+	}
+	$self->{values}{dynamic_config} = $_[0] ? 1 : 0;
+	return $self;
+}
+
+sub all_from {
+	my ( $self, $file ) = @_;
+
+	unless ( defined($file) ) {
+		my $name = $self->name
+			or die "all_from called with no args without setting name() first";
+		$file = join('/', 'lib', split(/-/, $name)) . '.pm';
+		$file =~ s{.*/}{} unless -e $file;
+		die "all_from: cannot find $file from $name" unless -e $file;
+	}
+
+	# Some methods pull from POD instead of code.
+	# If there is a matching .pod, use that instead
+	my $pod = $file;
+	$pod =~ s/\.pm$/.pod/i;
+	$pod = $file unless -e $pod;
+
+	# Pull the different values
+	$self->name_from($file)         unless $self->name;
+	$self->version_from($file)      unless $self->version;
+	$self->perl_version_from($file) unless $self->perl_version;
+	$self->author_from($pod)        unless $self->author;
+	$self->license_from($pod)       unless $self->license;
+	$self->abstract_from($pod)      unless $self->abstract;
+
+	return 1;
+}
+
+sub provides {
+	my $self     = shift;
+	my $provides = ( $self->{values}{provides} ||= {} );
+	%$provides = (%$provides, @_) if @_;
+	return $provides;
+}
+
+sub auto_provides {
+	my $self = shift;
+	return $self unless $self->is_admin;
+	unless (-e 'MANIFEST') {
+		warn "Cannot deduce auto_provides without a MANIFEST, skipping\n";
+		return $self;
+	}
+	# Avoid spurious warnings as we are not checking manifest here.
+	local $SIG{__WARN__} = sub {1};
+	require ExtUtils::Manifest;
+	local *ExtUtils::Manifest::manicheck = sub { return };
+
+	require Module::Build;
+	my $build = Module::Build->new(
+		dist_name    => $self->name,
+		dist_version => $self->version,
+		license      => $self->license,
+	);
+	$self->provides( %{ $build->find_dist_packages || {} } );
+}
+
+sub feature {
+	my $self     = shift;
+	my $name     = shift;
+	my $features = ( $self->{values}{features} ||= [] );
+	my $mods;
+
+	if ( @_ == 1 and ref( $_[0] ) ) {
+		# The user used ->feature like ->features by passing in the second
+		# argument as a reference.  Accomodate for that.
+		$mods = $_[0];
+	} else {
+		$mods = \@_;
+	}
+
+	my $count = 0;
+	push @$features, (
+		$name => [
+			map {
+				ref($_) ? ( ref($_) eq 'HASH' ) ? %$_ : @$_ : $_
+			} @$mods
+		]
+	);
+
+	return @$features;
+}
+
+sub features {
+	my $self = shift;
+	while ( my ( $name, $mods ) = splice( @_, 0, 2 ) ) {
+		$self->feature( $name, @$mods );
+	}
+	return $self->{values}->{features}
+		? @{ $self->{values}->{features} }
+		: ();
+}
+
+sub no_index {
+	my $self = shift;
+	my $type = shift;
+	push @{ $self->{values}{no_index}{$type} }, @_ if $type;
+	return $self->{values}{no_index};
+}
+
+sub read {
+	my $self = shift;
+	$self->include_deps( 'YAML::Tiny', 0 );
+
+	require YAML::Tiny;
+	my $data = YAML::Tiny::LoadFile('META.yml');
+
+	# Call methods explicitly in case user has already set some values.
+	while ( my ( $key, $value ) = each %$data ) {
+		next unless $self->can($key);
+		if ( ref $value eq 'HASH' ) {
+			while ( my ( $module, $version ) = each %$value ) {
+				$self->can($key)->($self, $module => $version );
+			}
+		} else {
+			$self->can($key)->($self, $value);
+		}
+	}
+	return $self;
+}
+
+sub write {
+	my $self = shift;
+	return $self unless $self->is_admin;
+	$self->admin->write_meta;
+	return $self;
+}
+
+sub version_from {
+	require ExtUtils::MM_Unix;
+	my ( $self, $file ) = @_;
+	$self->version( ExtUtils::MM_Unix->parse_version($file) );
+}
+
+sub abstract_from {
+	require ExtUtils::MM_Unix;
+	my ( $self, $file ) = @_;
+	$self->abstract(
+		bless(
+			{ DISTNAME => $self->name },
+			'ExtUtils::MM_Unix'
+		)->parse_abstract($file)
+	 );
+}
+
+sub name_from {
+	my $self = shift;
+	if (
+		Module::Install::_read($_[0]) =~ m/
+		^ \s*
+		package \s*
+		([\w:]+)
+		\s* ;
+		/ixms
+	) {
+		my $name = $1;
+		$name =~ s{::}{-}g;
+		$self->name($name);
+	} else {
+		die "Cannot determine name from $_[0]\n";
+		return;
+	}
+}
+
+sub perl_version_from {
+	my $self = shift;
+	if (
+		Module::Install::_read($_[0]) =~ m/
+		^
+		use \s*
+		v?
+		([\d_\.]+)
+		\s* ;
+		/ixms
+	) {
+		my $perl_version = $1;
+		$perl_version =~ s{_}{}g;
+		$self->perl_version($perl_version);
+	} else {
+		warn "Cannot determine perl version info from $_[0]\n";
+		return;
+	}
+}
+
+sub author_from {
+	my $self    = shift;
+	my $content = Module::Install::_read($_[0]);
+	if ($content =~ m/
+		=head \d \s+ (?:authors?)\b \s*
+		([^\n]*)
+		|
+		=head \d \s+ (?:licen[cs]e|licensing|copyright|legal)\b \s*
+		.*? copyright .*? \d\d\d[\d.]+ \s* (?:\bby\b)? \s*
+		([^\n]*)
+	/ixms) {
+		my $author = $1 || $2;
+		$author =~ s{E<lt>}{<}g;
+		$author =~ s{E<gt>}{>}g;
+		$self->author($author);
+	} else {
+		warn "Cannot determine author info from $_[0]\n";
+	}
+}
+
+sub license_from {
+	my $self = shift;
+	if (
+		Module::Install::_read($_[0]) =~ m/
+		(
+			=head \d \s+
+			(?:licen[cs]e|licensing|copyright|legal)\b
+			.*?
+		)
+		(=head\\d.*|=cut.*|)
+		\z
+	/ixms ) {
+		my $license_text = $1;
+		my @phrases      = (
+			'under the same (?:terms|license) as perl itself' => 'perl',        1,
+			'GNU public license'                              => 'gpl',         1,
+			'GNU lesser public license'                       => 'lgpl',        1,
+			'BSD license'                                     => 'bsd',         1,
+			'Artistic license'                                => 'artistic',    1,
+			'GPL'                                             => 'gpl',         1,
+			'LGPL'                                            => 'lgpl',        1,
+			'BSD'                                             => 'bsd',         1,
+			'Artistic'                                        => 'artistic',    1,
+			'MIT'                                             => 'mit',         1,
+			'proprietary'                                     => 'proprietary', 0,
+		);
+		while ( my ($pattern, $license, $osi) = splice(@phrases, 0, 3) ) {
+			$pattern =~ s{\s+}{\\s+}g;
+			if ( $license_text =~ /\b$pattern\b/i ) {
+				if ( $osi and $license_text =~ /All rights reserved/i ) {
+					warn "LEGAL WARNING: 'All rights reserved' may invalidate Open Source licenses. Consider removing it.";
+				}
+				$self->license($license);
+				return 1;
+			}
+		}
+	}
+
+	warn "Cannot determine license info from $_[0]\n";
+	return 'unknown';
+}
+
+sub install_script {
+	my $self = shift;
+	my $args = $self->makemaker_args;
+	my $exe  = $args->{EXE_FILES} ||= [];
+        foreach ( @_ ) {
+		if ( -f $_ ) {
+			push @$exe, $_;
+		} elsif ( -d 'script' and -f "script/$_" ) {
+			push @$exe, "script/$_";
+		} else {
+			die "Cannot find script '$_'";
+		}
+	}
+}
+
+1;
diff --git a/inc/Module/Install/RTx.pm b/inc/Module/Install/RTx.pm
new file mode 100644
index 0000000..c087b12
--- /dev/null
+++ b/inc/Module/Install/RTx.pm
@@ -0,0 +1,183 @@
+#line 1
+package Module::Install::RTx;
+
+use 5.008;
+use strict;
+use warnings;
+no warnings 'once';
+
+use Module::Install::Base;
+use base 'Module::Install::Base';
+our $VERSION = '0.22';
+
+use FindBin;
+use File::Glob     ();
+use File::Basename ();
+
+sub RTx {
+    my ( $self, $name ) = @_;
+
+    my $original_name = $name;
+    my $RTx = 'RTx';
+    $RTx = $1 if $name =~ s/^(\w+)-//;
+    my $fname = $name;
+    $fname =~ s!-!/!g;
+
+    $self->name("$RTx-$name")
+        unless $self->name;
+    $self->all_from( -e "$name.pm" ? "$name.pm" : "lib/$RTx/$fname.pm" )
+        unless $self->version;
+    $self->abstract("RT $name Extension")
+        unless $self->abstract;
+
+    my @prefixes = (qw(/opt /usr/local /home /usr /sw ));
+    my $prefix   = $ENV{PREFIX};
+    @ARGV = grep { /PREFIX=(.*)/ ? ( ( $prefix = $1 ), 0 ) : 1 } @ARGV;
+
+    if ($prefix) {
+        $RT::LocalPath = $prefix;
+        $INC{'RT.pm'} = "$RT::LocalPath/lib/RT.pm";
+    } else {
+        local @INC = (
+            @INC,
+            $ENV{RTHOME} ? ( $ENV{RTHOME}, "$ENV{RTHOME}/lib" ) : (),
+            map { ( "$_/rt3/lib", "$_/lib/rt3", "$_/lib" ) } grep $_,
+            @prefixes
+        );
+        until ( eval { require RT; $RT::LocalPath } ) {
+            warn
+                "Cannot find the location of RT.pm that defines \$RT::LocalPath in: @INC\n";
+            $_ = $self->prompt("Path to your RT.pm:") or exit;
+            push @INC, $_, "$_/rt3/lib", "$_/lib/rt3", "$_/lib";
+        }
+    }
+
+    my $lib_path = File::Basename::dirname( $INC{'RT.pm'} );
+    my $local_lib_path = "$RT::LocalPath/lib";
+    print "Using RT configuration from $INC{'RT.pm'}:\n";
+    unshift @INC, "$RT::LocalPath/lib" if $RT::LocalPath;
+
+    $RT::LocalVarPath  ||= $RT::VarPath;
+    $RT::LocalPoPath   ||= $RT::LocalLexiconPath;
+    $RT::LocalHtmlPath ||= $RT::MasonComponentRoot;
+
+    my %path;
+    my $with_subdirs = $ENV{WITH_SUBDIRS};
+    @ARGV = grep { /WITH_SUBDIRS=(.*)/ ? ( ( $with_subdirs = $1 ), 0 ) : 1 }
+        @ARGV;
+
+    my %subdirs;
+    %subdirs = map { $_ => 1 } split( /\s*,\s*/, $with_subdirs )
+        if defined $with_subdirs;
+
+    foreach (qw(bin etc html po sbin var)) {
+        next unless -d "$FindBin::Bin/$_";
+        next if keys %subdirs and !$subdirs{$_};
+        $self->no_index( directory => $_ );
+
+        no strict 'refs';
+        my $varname = "RT::Local" . ucfirst($_) . "Path";
+        $path{$_} = ${$varname} || "$RT::LocalPath/$_";
+    }
+
+    $path{$_} .= "/$name" for grep $path{$_}, qw(etc po var);
+    $path{lib} = "$RT::LocalPath/lib" unless keys %subdirs and !$subdirs{'lib'};
+
+    # If we're running on RT 3.8 with plugin support, we really wany
+    # to install libs, mason templates and po files into plugin specific
+    # directories
+    if ($RT::LocalPluginPath) {
+        foreach my $path (qw(lib po html etc bin sbin)) {
+            next unless -d "$FindBin::Bin/$path";
+            next if %subdirs and !$subdirs{$path};
+            $path{$path} = $RT::LocalPluginPath . "/$original_name/$path";
+        }
+    }
+
+    my $args = join( ', ', map "q($_)", %path );
+    print "./$_\t=> $path{$_}\n" for sort keys %path;
+
+    if ( my @dirs = map { ( -D => $_ ) } grep $path{$_}, qw(bin html sbin) ) {
+        my @po = map { ( -o => $_ ) } grep -f,
+            File::Glob::bsd_glob("po/*.po");
+        $self->postamble(<< ".") if @po;
+lexicons ::
+\t\$(NOECHO) \$(PERL) -MLocale::Maketext::Extract::Run=xgettext -e \"xgettext(qw(@dirs @po))\"
+.
+    }
+
+    my $postamble = << ".";
+install ::
+\t\$(NOECHO) \$(PERL) -MExtUtils::Install -e \"install({$args})\"
+.
+
+    if ( $path{var} and -d $RT::MasonDataDir ) {
+        my ( $uid, $gid ) = ( stat($RT::MasonDataDir) )[ 4, 5 ];
+        $postamble .= << ".";
+\t\$(NOECHO) chown -R $uid:$gid $path{var}
+.
+    }
+
+    my %has_etc;
+    if ( File::Glob::bsd_glob("$FindBin::Bin/etc/schema.*") ) {
+
+        # got schema, load factory module
+        $has_etc{schema}++;
+        $self->load('RTxFactory');
+        $self->postamble(<< ".");
+factory ::
+\t\$(NOECHO) \$(PERL) -Ilib -I"$local_lib_path" -I"$lib_path" -Minc::Module::Install -e"RTxFactory(qw($RTx $name))"
+
+dropdb ::
+\t\$(NOECHO) \$(PERL) -Ilib -I"$local_lib_path" -I"$lib_path" -Minc::Module::Install -e"RTxFactory(qw($RTx $name drop))"
+
+.
+    }
+    if ( File::Glob::bsd_glob("$FindBin::Bin/etc/acl.*") ) {
+        $has_etc{acl}++;
+    }
+    if ( -e 'etc/initialdata' ) { $has_etc{initialdata}++; }
+
+    $self->postamble("$postamble\n");
+    if ( %subdirs and !$subdirs{'lib'} ) {
+        $self->makemaker_args( PM => { "" => "" }, );
+    } else {
+        $self->makemaker_args( INSTALLSITELIB => "$RT::LocalPath/lib" );
+    }
+
+        $self->makemaker_args( INSTALLSITEMAN1DIR => "$RT::LocalPath/man/man1" );
+        $self->makemaker_args( INSTALLSITEMAN3DIR => "$RT::LocalPath/man/man3" );
+        $self->makemaker_args( INSTALLSITEARCH => "$RT::LocalPath/man" );
+        $self->makemaker_args( INSTALLARCHLIB => "$RT::LocalPath/lib" );
+    if (%has_etc) {
+        $self->load('RTxInitDB');
+        print "For first-time installation, type 'make initdb'.\n";
+        my $initdb = '';
+        $initdb .= <<"." if $has_etc{schema};
+\t\$(NOECHO) \$(PERL) -Ilib -I"$local_lib_path" -I"$lib_path" -Minc::Module::Install -e"RTxInitDB(qw(schema))"
+.
+        $initdb .= <<"." if $has_etc{acl};
+\t\$(NOECHO) \$(PERL) -Ilib -I"$local_lib_path" -I"$lib_path" -Minc::Module::Install -e"RTxInitDB(qw(acl))"
+.
+        $initdb .= <<"." if $has_etc{initialdata};
+\t\$(NOECHO) \$(PERL) -Ilib -I"$local_lib_path" -I"$lib_path" -Minc::Module::Install -e"RTxInitDB(qw(insert))"
+.
+        $self->postamble("initdb ::\n$initdb\n");
+        $self->postamble("initialize-database ::\n$initdb\n");
+    }
+}
+
+sub RTxInit {
+    unshift @INC, substr( delete( $INC{'RT.pm'} ), 0, -5 ) if $INC{'RT.pm'};
+    require RT;
+    RT::LoadConfig();
+    RT::ConnectToDatabase();
+
+    die "Cannot load RT" unless $RT::Handle and $RT::DatabaseType;
+}
+
+1;
+
+__END__
+
+#line 281
diff --git a/lib/RT/FM/Article_Overlay.pm b/lib/RT/FM/Article_Overlay.pm
new file mode 100644
index 0000000..9d0079d
--- /dev/null
+++ b/lib/RT/FM/Article_Overlay.pm
@@ -0,0 +1,81 @@
+# BEGIN LICENSE BLOCK
+#
+#  Copyright (c) 2002-2008 Jesse Vincent <jesse at bestpractical.com>
+#
+#  This program is free software; you can redistribute it and/or modify
+#  it under the terms of version 2 of the GNU General Public License
+#  as published by the Free Software Foundation.
+#
+#  A copy of that license should have arrived with this
+#  software, but in any event can be snarfed from www.gnu.org.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+# END LICENSE BLOCK
+
+package RT::FM::Article;
+use strict;
+no warnings qw/redefine/;
+
+=head2 ParseTemplate $CONTENT, %TEMPLATE_ARGS
+
+Parses $CONTENT string as a template (L<Text::Template>).
+$Article and other arguments from %TEMPLATE_ARGS are
+available in code of the template as perl variables.
+
+=cut
+
+sub ParseTemplate {
+    my $self = shift;
+    my $content = shift;
+    my %args = (
+        Ticket => undef,
+        @_
+    );
+
+    return ($content) unless defined $content && length $content;
+
+    $args{'Article'} = $self;
+    $args{'rtname'}  = $RT::rtname;
+    if ( $args{'Ticket'} ) {
+        my $t = $args{'Ticket'}; # avoid memory leak
+        $args{'loc'} = sub { $t->loc(@_) };
+    } else {
+        $args{'loc'} = sub { $self->loc(@_) };
+    }
+
+    foreach my $key ( keys %args ) {
+        next unless ref $args{ $key };
+        next if ref $args{ $key } =~ /^(ARRAY|HASH|SCALAR|CODE)$/;
+        my $val = $args{ $key };
+        $args{ $key } = \$val;
+    }
+
+    # We need to untaint the content of the template, since we'll be working
+    # with it
+    $content =~ s/^(.*)$/$1/;
+    my $template = Text::Template->new(
+        TYPE   => 'STRING',
+        SOURCE => $content
+    );
+
+    my $is_broken = 0;
+    my $retval = $template->fill_in(
+        HASH => \%args,
+        BROKEN => sub {
+            my (%args) = @_;
+            $RT::Logger->error("Article parsing error: $args{error}")
+                unless $args{error} =~ /^Died at /; # ignore intentional die()
+            $is_broken++;
+            return undef;
+        },
+    );
+    return ( undef, $self->loc('Article parsing error') ) if $is_broken;
+
+    return ($retval);
+}
+
+1
diff --git a/lib/RTFM/Extension/ArticleTemplates.pm b/lib/RTFM/Extension/ArticleTemplates.pm
new file mode 100644
index 0000000..4bbfd94
--- /dev/null
+++ b/lib/RTFM/Extension/ArticleTemplates.pm
@@ -0,0 +1,162 @@
+package RTFM::Extension::ArticleTemplates;
+
+our $VERSION = '0.01';
+
+use warnings;
+use strict;
+use Carp;
+
+
+=head1 NAME
+
+RTFM::Extension::ArticleTemplates - [One line description of module's purpose here]
+
+
+=head1 SYNOPSIS
+
+    use RTFM::Extension::ArticleTemplates;
+
+=for author to fill in:
+    Brief code example(s) here showing commonest usage(s).
+    This section will be as far as many users bother reading
+    so make it as educational and exeplary as possible.
+  
+  
+=head1 DESCRIPTION
+
+=for author to fill in:
+    Write a full description of the module and its features here.
+    Use subsections (=head2, =head3) as appropriate.
+
+
+=head1 METHODS
+
+=cut
+
+=head2 bla
+
+This is a method.
+
+=cut
+
+sub bla {
+    my $self = shift;`
+} 
+
+
+
+=head1 DIAGNOSTICS
+
+=for author to fill in:
+    List every single error and warning message that the module can
+    generate (even the ones that will "never happen"), with a full
+    explanation of each problem, one or more likely causes, and any
+    suggested remedies.
+
+=over
+
+=item C<< Error message here, perhaps with %s placeholders >>
+
+[Description of error here]
+
+=item C<< Another error message here >>
+
+[Description of error here]
+
+[Et cetera, et cetera]
+
+=back
+
+
+=head1 CONFIGURATION AND ENVIRONMENT
+
+=for author to fill in:
+    A full explanation of any configuration system(s) used by the
+    module, including the names and locations of any configuration
+    files, and the meaning of any environment variables or properties
+    that can be set. These descriptions must also include details of any
+    configuration language used.
+  
+RTFM::Extension::ArticleTemplates requires no configuration files or environment variables.
+
+
+=head1 DEPENDENCIES
+
+=for author to fill in:
+    A list of all the other modules that this module relies upon,
+    including any restrictions on versions, and an indication whether
+    the module is part of the standard Perl distribution, part of the
+    module's distribution, or must be installed separately. ]
+
+None.
+
+
+=head1 INCOMPATIBILITIES
+
+=for author to fill in:
+    A list of any modules that this module cannot be used in conjunction
+    with. This may be due to name conflicts in the interface, or
+    competition for system or program resources, or due to internal
+    limitations of Perl (for example, many modules that use source code
+    filters are mutually incompatible).
+
+None reported.
+
+
+=head1 BUGS AND LIMITATIONS
+
+=for author to fill in:
+    A list of known problems with the module, together with some
+    indication Whether they are likely to be fixed in an upcoming
+    release. Also a list of restrictions on the features the module
+    does provide: data types that cannot be handled, performance issues
+    and the circumstances in which they may arise, practical
+    limitations on the size of data sets, special cases that are not
+    (yet) handled, etc.
+
+No bugs have been reported.
+
+Please report any bugs or feature requests to
+C<bug-rtfm-extension-articletemplates at rt.cpan.org>, or through the web interface at
+L<http://rt.cpan.org>.
+
+
+=head1 AUTHOR
+
+Kevin Falcone  C<< <falcone at bestpractical.com> >>
+
+
+=head1 LICENCE AND COPYRIGHT
+
+Copyright (c) 2008, Best Practical Solutions, LLC.  All rights reserved.
+
+This module is free software; you can redistribute it and/or
+modify it under the terms of version 2 of the GNU General Public License.
+
+
+=head1 DISCLAIMER OF WARRANTY
+
+BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
+EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
+ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH
+YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
+NECESSARY SERVICING, REPAIR, OR CORRECTION.
+
+IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE
+LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL,
+OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
+THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+=cut
+
+1;
diff --git a/t/00.load.t b/t/00.load.t
new file mode 100644
index 0000000..7d03e94
--- /dev/null
+++ b/t/00.load.t
@@ -0,0 +1,7 @@
+use Test::More tests => 1;
+
+BEGIN {
+use_ok( 'RTFM::Extension::ArticleTemplates' );
+}
+
+diag( "Testing RTFM::Extension::ArticleTemplates $RTFM::Extension::ArticleTemplates::VERSION" );
diff --git a/t/pod-coverage.t b/t/pod-coverage.t
new file mode 100644
index 0000000..703f91d
--- /dev/null
+++ b/t/pod-coverage.t
@@ -0,0 +1,6 @@
+#!perl -T
+
+use Test::More;
+eval "use Test::Pod::Coverage 1.04";
+plan skip_all => "Test::Pod::Coverage 1.04 required for testing POD coverage" if $@;
+all_pod_coverage_ok();
diff --git a/t/pod.t b/t/pod.t
new file mode 100644
index 0000000..976d7cd
--- /dev/null
+++ b/t/pod.t
@@ -0,0 +1,6 @@
+#!perl -T
+
+use Test::More;
+eval "use Test::Pod 1.14";
+plan skip_all => "Test::Pod 1.14 required for testing POD" if $@;
+all_pod_files_ok();

commit e72bde78b77c1521136f7ce495212e23b3acbfea
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Mon May 12 21:30:19 2008 +0000

    rename Article_Overlay.pm -> Article_Local.pm

diff --git a/lib/RT/FM/Article_Overlay.pm b/lib/RT/FM/Article_Local.pm
similarity index 100%
rename from lib/RT/FM/Article_Overlay.pm
rename to lib/RT/FM/Article_Local.pm

commit c20d57e4fdba420d3ccfdad1e22a27d1c3203a9f
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Mon May 12 21:31:09 2008 +0000

    $content is a reference

diff --git a/html/Callbacks/RTFM-Extension-ArticleTemplates/RTFM/Article/Elements/Preformatted/ProcessContent b/html/Callbacks/RTFM-Extension-ArticleTemplates/RTFM/Article/Elements/Preformatted/ProcessContent
index 9b9606b..bb10e75 100644
--- a/html/Callbacks/RTFM-Extension-ArticleTemplates/RTFM/Article/Elements/Preformatted/ProcessContent
+++ b/html/Callbacks/RTFM-Extension-ArticleTemplates/RTFM/Article/Elements/Preformatted/ProcessContent
@@ -16,11 +16,11 @@
 %# 
 %# END LICENSE BLOCK
 <%init>
-my ($new, $msg) = $Article->ParseTemplate( $content, Ticket => $Ticket );
+my ($new, $msg) = $Article->ParseTemplate( $$content, Ticket => $Ticket );
 unless ( defined $new && length $new ) {
     $RT::Logger->error("Couldn't parse article's content: $msg");
 } else {
-    $content = $new;
+    $$content = $new;
 }
 </%init>
 <%args>

commit 248f916baf239092ea4c18dc7d8f2792ffd869c1
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Mon May 12 22:19:44 2008 +0000

    docs

diff --git a/lib/RTFM/Extension/ArticleTemplates.pm b/lib/RTFM/Extension/ArticleTemplates.pm
index 4bbfd94..f77ae4e 100644
--- a/lib/RTFM/Extension/ArticleTemplates.pm
+++ b/lib/RTFM/Extension/ArticleTemplates.pm
@@ -2,129 +2,43 @@ package RTFM::Extension::ArticleTemplates;
 
 our $VERSION = '0.01';
 
-use warnings;
 use strict;
-use Carp;
-
+use warnings;
 
 =head1 NAME
 
-RTFM::Extension::ArticleTemplates - [One line description of module's purpose here]
-
-
-=head1 SYNOPSIS
+RTFM::Extension::ArticleTemplates - turns articles' custom fields into templates.
 
-    use RTFM::Extension::ArticleTemplates;
-
-=for author to fill in:
-    Brief code example(s) here showing commonest usage(s).
-    This section will be as far as many users bother reading
-    so make it as educational and exeplary as possible.
-  
-  
 =head1 DESCRIPTION
 
-=for author to fill in:
-    Write a full description of the module and its features here.
-    Use subsections (=head2, =head3) as appropriate.
-
-
-=head1 METHODS
-
-=cut
-
-=head2 bla
-
-This is a method.
-
-=cut
-
-sub bla {
-    my $self = shift;`
-} 
-
-
-
-=head1 DIAGNOSTICS
-
-=for author to fill in:
-    List every single error and warning message that the module can
-    generate (even the ones that will "never happen"), with a full
-    explanation of each problem, one or more likely causes, and any
-    suggested remedies.
-
-=over
+When this extension is installed RTFM parses content of articles as
+a template using L<Text::Template> module. Using this extension you can
+make your articles dynamic. L<Text::Template> module is used to parse
+RT's Templates as well and its syntax is pretty simple - you can consult
+RT docs/wiki or module's documentation.
 
-=item C<< Error message here, perhaps with %s placeholders >>
+=head1 VERY IMPORTANT
 
-[Description of error here]
+It's a B<SECURITY RISK> to install this extension on systems where
+articles can be changed by not trusted users. You're warned!
 
-=item C<< Another error message here >>
+Your articles may contain some text that looks like a template and
+will be parsed after installation when it's actually is not valid
+template.
 
-[Description of error here]
+=head1 INSTALLATION
 
-[Et cetera, et cetera]
-
-=back
-
-
-=head1 CONFIGURATION AND ENVIRONMENT
-
-=for author to fill in:
-    A full explanation of any configuration system(s) used by the
-    module, including the names and locations of any configuration
-    files, and the meaning of any environment variables or properties
-    that can be set. These descriptions must also include details of any
-    configuration language used.
-  
-RTFM::Extension::ArticleTemplates requires no configuration files or environment variables.
-
-
-=head1 DEPENDENCIES
-
-=for author to fill in:
-    A list of all the other modules that this module relies upon,
-    including any restrictions on versions, and an indication whether
-    the module is part of the standard Perl distribution, part of the
-    module's distribution, or must be installed separately. ]
-
-None.
-
-
-=head1 INCOMPATIBILITIES
-
-=for author to fill in:
-    A list of any modules that this module cannot be used in conjunction
-    with. This may be due to name conflicts in the interface, or
-    competition for system or program resources, or due to internal
-    limitations of Perl (for example, many modules that use source code
-    filters are mutually incompatible).
-
-None reported.
-
-
-=head1 BUGS AND LIMITATIONS
-
-=for author to fill in:
-    A list of known problems with the module, together with some
-    indication Whether they are likely to be fixed in an upcoming
-    release. Also a list of restrictions on the features the module
-    does provide: data types that cannot be handled, performance issues
-    and the circumstances in which they may arise, practical
-    limitations on the size of data sets, special cases that are not
-    (yet) handled, etc.
-
-No bugs have been reported.
-
-Please report any bugs or feature requests to
-C<bug-rtfm-extension-articletemplates at rt.cpan.org>, or through the web interface at
-L<http://rt.cpan.org>.
+This extension requires RTFM 2.2.2 at least. To install it run the following
+commands:
 
+    perl Makefile.PL
+    make
+    make install
 
 =head1 AUTHOR
 
 Kevin Falcone  C<< <falcone at bestpractical.com> >>
-
+Ruslan Zakirov C<< <ruz at bestpractical.com> >>
 
 =head1 LICENCE AND COPYRIGHT
 
@@ -133,30 +47,6 @@ Copyright (c) 2008, Best Practical Solutions, LLC.  All rights reserved.
 This module is free software; you can redistribute it and/or
 modify it under the terms of version 2 of the GNU General Public License.
 
-
-=head1 DISCLAIMER OF WARRANTY
-
-BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
-EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
-ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH
-YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
-NECESSARY SERVICING, REPAIR, OR CORRECTION.
-
-IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE
-LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL,
-OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
-THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
 =cut
 
 1;

commit 40c82616ab6a1a77451ef01b0a6ea432552f9592
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Mon May 12 22:20:04 2008 +0000

    update readme

diff --git a/README b/README
index d34d794..03e7204 100644
--- a/README
+++ b/README
@@ -1,39 +1 @@
-RTFM-Extension-ArticleTemplates version 0.0.1
-
-[ REPLACE THIS...
-
-  The README is used to introduce the module and provide instructions on
-  how to install the module, any machine dependencies it may have (for
-  example C compilers and installed libraries) and any other information
-  that should be understood before the module is installed.
-
-  A README file is required for CPAN modules since CPAN extracts the
-  README file from a module distribution so that people browsing the
-  archive can use it get an idea of the modules uses. It is usually a
-  good idea to provide version information here so that people can
-  decide whether fixes for the module are worth downloading.
-]
-
-
-INSTALLATION
-
-To install this module, run the following commands:
-
-	perl Makefile.PL
-	make
-	make test
-	make install
-
-
-DEPENDENCIES
-
-None.
-
-
-COPYRIGHT AND LICENCE
-
-Copyright (C) 2008, Best Practical Solutions LLC.
-
-This library is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
+Read `perldoc lib/RTFM/Extension/ArticleTemplates.pm`.

commit e411488a049e9710e138413e126a66c8b2034357
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Mon May 12 22:34:57 2008 +0000

    releng things

diff --git a/META.yml b/META.yml
new file mode 100644
index 0000000..a133b74
--- /dev/null
+++ b/META.yml
@@ -0,0 +1,22 @@
+---
+abstract: 'turns articles into dynamic templates.'
+author:
+  - 'Kevin Falcone <falcone at bestpractical.com>'
+build_requires:
+  Test::More: 0
+distribution_type: module
+generated_by: 'Module::Install version 0.72'
+license: 'GPL version 2'
+meta-spec:
+  url: http://module-build.sourceforge.net/META-spec-v1.3.html
+  version: 1.3
+name: RTFM-Extension-ArticleTemplates
+no_index:
+  directory:
+    - html
+    - inc
+    - t
+requires:
+  RT::FM: 2.2.2
+  perl: 5.8.3
+version: 0.01
diff --git a/Makefile.PL b/Makefile.PL
index 17aedd0..82613f7 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -1,12 +1,16 @@
 use inc::Module::Install;
 
-RTx 'RTFM-Extension-ArticleTemplates';
-license 'GPL Version 2';
-all_from 'lib/RTFM/Extension/ArticleTemplates.pm';
-author   'Kevin Falcone <falcone at bestpractical.com>';
+RTx         'RTFM-Extension-ArticleTemplates';
+license     'GPL version 2';
+all_from    'lib/RTFM/Extension/ArticleTemplates.pm';
 
 build_requires 'Test::More';
-requires('RT::FM' => 2.2.2);
+# XXX: This should be reported by M::I::RTx
+my ($lib_path) = $INC{'RT.pm'} =~ /^(.*)[\\\/]/;
+my $local_lib_path = "$RT::LocalPath/lib";
+
+unshift @INC, $local_lib_path, $lib_path;
+requires('RT::FM' => '2.2.2');
 
 auto_install;
 
diff --git a/inc/Module/AutoInstall.pm b/inc/Module/AutoInstall.pm
new file mode 100644
index 0000000..7efc552
--- /dev/null
+++ b/inc/Module/AutoInstall.pm
@@ -0,0 +1,768 @@
+#line 1
+package Module::AutoInstall;
+
+use strict;
+use Cwd                 ();
+use ExtUtils::MakeMaker ();
+
+use vars qw{$VERSION};
+BEGIN {
+	$VERSION = '1.03';
+}
+
+# special map on pre-defined feature sets
+my %FeatureMap = (
+    ''      => 'Core Features',    # XXX: deprecated
+    '-core' => 'Core Features',
+);
+
+# various lexical flags
+my ( @Missing, @Existing,  %DisabledTests, $UnderCPAN,     $HasCPANPLUS );
+my ( $Config,  $CheckOnly, $SkipInstall,   $AcceptDefault, $TestOnly );
+my ( $PostambleActions, $PostambleUsed );
+
+# See if it's a testing or non-interactive session
+_accept_default( $ENV{AUTOMATED_TESTING} or ! -t STDIN ); 
+_init();
+
+sub _accept_default {
+    $AcceptDefault = shift;
+}
+
+sub missing_modules {
+    return @Missing;
+}
+
+sub do_install {
+    __PACKAGE__->install(
+        [
+            $Config
+            ? ( UNIVERSAL::isa( $Config, 'HASH' ) ? %{$Config} : @{$Config} )
+            : ()
+        ],
+        @Missing,
+    );
+}
+
+# initialize various flags, and/or perform install
+sub _init {
+    foreach my $arg (
+        @ARGV,
+        split(
+            /[\s\t]+/,
+            $ENV{PERL_AUTOINSTALL} || $ENV{PERL_EXTUTILS_AUTOINSTALL} || ''
+        )
+      )
+    {
+        if ( $arg =~ /^--config=(.*)$/ ) {
+            $Config = [ split( ',', $1 ) ];
+        }
+        elsif ( $arg =~ /^--installdeps=(.*)$/ ) {
+            __PACKAGE__->install( $Config, @Missing = split( /,/, $1 ) );
+            exit 0;
+        }
+        elsif ( $arg =~ /^--default(?:deps)?$/ ) {
+            $AcceptDefault = 1;
+        }
+        elsif ( $arg =~ /^--check(?:deps)?$/ ) {
+            $CheckOnly = 1;
+        }
+        elsif ( $arg =~ /^--skip(?:deps)?$/ ) {
+            $SkipInstall = 1;
+        }
+        elsif ( $arg =~ /^--test(?:only)?$/ ) {
+            $TestOnly = 1;
+        }
+    }
+}
+
+# overrides MakeMaker's prompt() to automatically accept the default choice
+sub _prompt {
+    goto &ExtUtils::MakeMaker::prompt unless $AcceptDefault;
+
+    my ( $prompt, $default ) = @_;
+    my $y = ( $default =~ /^[Yy]/ );
+
+    print $prompt, ' [', ( $y ? 'Y' : 'y' ), '/', ( $y ? 'n' : 'N' ), '] ';
+    print "$default\n";
+    return $default;
+}
+
+# the workhorse
+sub import {
+    my $class = shift;
+    my @args  = @_ or return;
+    my $core_all;
+
+    print "*** $class version " . $class->VERSION . "\n";
+    print "*** Checking for Perl dependencies...\n";
+
+    my $cwd = Cwd::cwd();
+
+    $Config = [];
+
+    my $maxlen = length(
+        (
+            sort   { length($b) <=> length($a) }
+              grep { /^[^\-]/ }
+              map  {
+                ref($_)
+                  ? ( ( ref($_) eq 'HASH' ) ? keys(%$_) : @{$_} )
+                  : ''
+              }
+              map { +{@args}->{$_} }
+              grep { /^[^\-]/ or /^-core$/i } keys %{ +{@args} }
+        )[0]
+    );
+
+    while ( my ( $feature, $modules ) = splice( @args, 0, 2 ) ) {
+        my ( @required, @tests, @skiptests );
+        my $default  = 1;
+        my $conflict = 0;
+
+        if ( $feature =~ m/^-(\w+)$/ ) {
+            my $option = lc($1);
+
+            # check for a newer version of myself
+            _update_to( $modules, @_ ) and return if $option eq 'version';
+
+            # sets CPAN configuration options
+            $Config = $modules if $option eq 'config';
+
+            # promote every features to core status
+            $core_all = ( $modules =~ /^all$/i ) and next
+              if $option eq 'core';
+
+            next unless $option eq 'core';
+        }
+
+        print "[" . ( $FeatureMap{ lc($feature) } || $feature ) . "]\n";
+
+        $modules = [ %{$modules} ] if UNIVERSAL::isa( $modules, 'HASH' );
+
+        unshift @$modules, -default => &{ shift(@$modules) }
+          if ( ref( $modules->[0] ) eq 'CODE' );    # XXX: bugward combatability
+
+        while ( my ( $mod, $arg ) = splice( @$modules, 0, 2 ) ) {
+            if ( $mod =~ m/^-(\w+)$/ ) {
+                my $option = lc($1);
+
+                $default   = $arg    if ( $option eq 'default' );
+                $conflict  = $arg    if ( $option eq 'conflict' );
+                @tests     = @{$arg} if ( $option eq 'tests' );
+                @skiptests = @{$arg} if ( $option eq 'skiptests' );
+
+                next;
+            }
+
+            printf( "- %-${maxlen}s ...", $mod );
+
+            if ( $arg and $arg =~ /^\D/ ) {
+                unshift @$modules, $arg;
+                $arg = 0;
+            }
+
+            # XXX: check for conflicts and uninstalls(!) them.
+            if (
+                defined( my $cur = _version_check( _load($mod), $arg ||= 0 ) ) )
+            {
+                print "loaded. ($cur" . ( $arg ? " >= $arg" : '' ) . ")\n";
+                push @Existing, $mod => $arg;
+                $DisabledTests{$_} = 1 for map { glob($_) } @skiptests;
+            }
+            else {
+                print "missing." . ( $arg ? " (would need $arg)" : '' ) . "\n";
+                push @required, $mod => $arg;
+            }
+        }
+
+        next unless @required;
+
+        my $mandatory = ( $feature eq '-core' or $core_all );
+
+        if (
+            !$SkipInstall
+            and (
+                $CheckOnly
+                or _prompt(
+                    qq{==> Auto-install the }
+                      . ( @required / 2 )
+                      . ( $mandatory ? ' mandatory' : ' optional' )
+                      . qq{ module(s) from CPAN?},
+                    $default ? 'y' : 'n',
+                ) =~ /^[Yy]/
+            )
+          )
+        {
+            push( @Missing, @required );
+            $DisabledTests{$_} = 1 for map { glob($_) } @skiptests;
+        }
+
+        elsif ( !$SkipInstall
+            and $default
+            and $mandatory
+            and
+            _prompt( qq{==> The module(s) are mandatory! Really skip?}, 'n', )
+            =~ /^[Nn]/ )
+        {
+            push( @Missing, @required );
+            $DisabledTests{$_} = 1 for map { glob($_) } @skiptests;
+        }
+
+        else {
+            $DisabledTests{$_} = 1 for map { glob($_) } @tests;
+        }
+    }
+
+    $UnderCPAN = _check_lock();    # check for $UnderCPAN
+
+    if ( @Missing and not( $CheckOnly or $UnderCPAN ) ) {
+        require Config;
+        print
+"*** Dependencies will be installed the next time you type '$Config::Config{make}'.\n";
+
+        # make an educated guess of whether we'll need root permission.
+        print "    (You may need to do that as the 'root' user.)\n"
+          if eval '$>';
+    }
+    print "*** $class configuration finished.\n";
+
+    chdir $cwd;
+
+    # import to main::
+    no strict 'refs';
+    *{'main::WriteMakefile'} = \&Write if caller(0) eq 'main';
+}
+
+# Check to see if we are currently running under CPAN.pm and/or CPANPLUS;
+# if we are, then we simply let it taking care of our dependencies
+sub _check_lock {
+    return unless @Missing;
+
+    if ($ENV{PERL5_CPANPLUS_IS_RUNNING}) {
+        print <<'END_MESSAGE';
+
+*** Since we're running under CPANPLUS, I'll just let it take care
+    of the dependency's installation later.
+END_MESSAGE
+        return 1;
+    }
+
+    _load_cpan();
+
+    # Find the CPAN lock-file
+    my $lock = MM->catfile( $CPAN::Config->{cpan_home}, ".lock" );
+    return unless -f $lock;
+
+    # Check the lock
+    local *LOCK;
+    return unless open(LOCK, $lock);
+
+    if (
+            ( $^O eq 'MSWin32' ? _under_cpan() : <LOCK> == getppid() )
+        and ( $CPAN::Config->{prerequisites_policy} || '' ) ne 'ignore'
+    ) {
+        print <<'END_MESSAGE';
+
+*** Since we're running under CPAN, I'll just let it take care
+    of the dependency's installation later.
+END_MESSAGE
+        return 1;
+    }
+
+    close LOCK;
+    return;
+}
+
+sub install {
+    my $class = shift;
+
+    my $i;    # used below to strip leading '-' from config keys
+    my @config = ( map { s/^-// if ++$i; $_ } @{ +shift } );
+
+    my ( @modules, @installed );
+    while ( my ( $pkg, $ver ) = splice( @_, 0, 2 ) ) {
+
+        # grep out those already installed
+        if ( defined( _version_check( _load($pkg), $ver ) ) ) {
+            push @installed, $pkg;
+        }
+        else {
+            push @modules, $pkg, $ver;
+        }
+    }
+
+    return @installed unless @modules;  # nothing to do
+    return @installed if _check_lock(); # defer to the CPAN shell
+
+    print "*** Installing dependencies...\n";
+
+    return unless _connected_to('cpan.org');
+
+    my %args = @config;
+    my %failed;
+    local *FAILED;
+    if ( $args{do_once} and open( FAILED, '.#autoinstall.failed' ) ) {
+        while (<FAILED>) { chomp; $failed{$_}++ }
+        close FAILED;
+
+        my @newmod;
+        while ( my ( $k, $v ) = splice( @modules, 0, 2 ) ) {
+            push @newmod, ( $k => $v ) unless $failed{$k};
+        }
+        @modules = @newmod;
+    }
+
+    if ( _has_cpanplus() ) {
+        _install_cpanplus( \@modules, \@config );
+    } else {
+        _install_cpan( \@modules, \@config );
+    }
+
+    print "*** $class installation finished.\n";
+
+    # see if we have successfully installed them
+    while ( my ( $pkg, $ver ) = splice( @modules, 0, 2 ) ) {
+        if ( defined( _version_check( _load($pkg), $ver ) ) ) {
+            push @installed, $pkg;
+        }
+        elsif ( $args{do_once} and open( FAILED, '>> .#autoinstall.failed' ) ) {
+            print FAILED "$pkg\n";
+        }
+    }
+
+    close FAILED if $args{do_once};
+
+    return @installed;
+}
+
+sub _install_cpanplus {
+    my @modules   = @{ +shift };
+    my @config    = _cpanplus_config( @{ +shift } );
+    my $installed = 0;
+
+    require CPANPLUS::Backend;
+    my $cp   = CPANPLUS::Backend->new;
+    my $conf = $cp->configure_object;
+
+    return unless $conf->can('conf') # 0.05x+ with "sudo" support
+               or _can_write($conf->_get_build('base'));  # 0.04x
+
+    # if we're root, set UNINST=1 to avoid trouble unless user asked for it.
+    my $makeflags = $conf->get_conf('makeflags') || '';
+    if ( UNIVERSAL::isa( $makeflags, 'HASH' ) ) {
+        # 0.03+ uses a hashref here
+        $makeflags->{UNINST} = 1 unless exists $makeflags->{UNINST};
+
+    } else {
+        # 0.02 and below uses a scalar
+        $makeflags = join( ' ', split( ' ', $makeflags ), 'UNINST=1' )
+          if ( $makeflags !~ /\bUNINST\b/ and eval qq{ $> eq '0' } );
+
+    }
+    $conf->set_conf( makeflags => $makeflags );
+    $conf->set_conf( prereqs   => 1 );
+
+    
+
+    while ( my ( $key, $val ) = splice( @config, 0, 2 ) ) {
+        $conf->set_conf( $key, $val );
+    }
+
+    my $modtree = $cp->module_tree;
+    while ( my ( $pkg, $ver ) = splice( @modules, 0, 2 ) ) {
+        print "*** Installing $pkg...\n";
+
+        MY::preinstall( $pkg, $ver ) or next if defined &MY::preinstall;
+
+        my $success;
+        my $obj = $modtree->{$pkg};
+
+        if ( $obj and defined( _version_check( $obj->{version}, $ver ) ) ) {
+            my $pathname = $pkg;
+            $pathname =~ s/::/\\W/;
+
+            foreach my $inc ( grep { m/$pathname.pm/i } keys(%INC) ) {
+                delete $INC{$inc};
+            }
+
+            my $rv = $cp->install( modules => [ $obj->{module} ] );
+
+            if ( $rv and ( $rv->{ $obj->{module} } or $rv->{ok} ) ) {
+                print "*** $pkg successfully installed.\n";
+                $success = 1;
+            } else {
+                print "*** $pkg installation cancelled.\n";
+                $success = 0;
+            }
+
+            $installed += $success;
+        } else {
+            print << ".";
+*** Could not find a version $ver or above for $pkg; skipping.
+.
+        }
+
+        MY::postinstall( $pkg, $ver, $success ) if defined &MY::postinstall;
+    }
+
+    return $installed;
+}
+
+sub _cpanplus_config {
+	my @config = ();
+	while ( @_ ) {
+		my ($key, $value) = (shift(), shift());
+		if ( $key eq 'prerequisites_policy' ) {
+			if ( $value eq 'follow' ) {
+				$value = CPANPLUS::Internals::Constants::PREREQ_INSTALL();
+			} elsif ( $value eq 'ask' ) {
+				$value = CPANPLUS::Internals::Constants::PREREQ_ASK();
+			} elsif ( $value eq 'ignore' ) {
+				$value = CPANPLUS::Internals::Constants::PREREQ_IGNORE();
+			} else {
+				die "*** Cannot convert option $key = '$value' to CPANPLUS version.\n";
+			}
+		} else {
+			die "*** Cannot convert option $key to CPANPLUS version.\n";
+		}
+	}
+	return @config;
+}
+
+sub _install_cpan {
+    my @modules   = @{ +shift };
+    my @config    = @{ +shift };
+    my $installed = 0;
+    my %args;
+
+    _load_cpan();
+    require Config;
+
+    if (CPAN->VERSION < 1.80) {
+        # no "sudo" support, probe for writableness
+        return unless _can_write( MM->catfile( $CPAN::Config->{cpan_home}, 'sources' ) )
+                  and _can_write( $Config::Config{sitelib} );
+    }
+
+    # if we're root, set UNINST=1 to avoid trouble unless user asked for it.
+    my $makeflags = $CPAN::Config->{make_install_arg} || '';
+    $CPAN::Config->{make_install_arg} =
+      join( ' ', split( ' ', $makeflags ), 'UNINST=1' )
+      if ( $makeflags !~ /\bUNINST\b/ and eval qq{ $> eq '0' } );
+
+    # don't show start-up info
+    $CPAN::Config->{inhibit_startup_message} = 1;
+
+    # set additional options
+    while ( my ( $opt, $arg ) = splice( @config, 0, 2 ) ) {
+        ( $args{$opt} = $arg, next )
+          if $opt =~ /^force$/;    # pseudo-option
+        $CPAN::Config->{$opt} = $arg;
+    }
+
+    local $CPAN::Config->{prerequisites_policy} = 'follow';
+
+    while ( my ( $pkg, $ver ) = splice( @modules, 0, 2 ) ) {
+        MY::preinstall( $pkg, $ver ) or next if defined &MY::preinstall;
+
+        print "*** Installing $pkg...\n";
+
+        my $obj     = CPAN::Shell->expand( Module => $pkg );
+        my $success = 0;
+
+        if ( $obj and defined( _version_check( $obj->cpan_version, $ver ) ) ) {
+            my $pathname = $pkg;
+            $pathname =~ s/::/\\W/;
+
+            foreach my $inc ( grep { m/$pathname.pm/i } keys(%INC) ) {
+                delete $INC{$inc};
+            }
+
+            my $rv = $args{force} ? CPAN::Shell->force( install => $pkg )
+                                  : CPAN::Shell->install($pkg);
+            $rv ||= eval {
+                $CPAN::META->instance( 'CPAN::Distribution', $obj->cpan_file, )
+                  ->{install}
+                  if $CPAN::META;
+            };
+
+            if ( $rv eq 'YES' ) {
+                print "*** $pkg successfully installed.\n";
+                $success = 1;
+            }
+            else {
+                print "*** $pkg installation failed.\n";
+                $success = 0;
+            }
+
+            $installed += $success;
+        }
+        else {
+            print << ".";
+*** Could not find a version $ver or above for $pkg; skipping.
+.
+        }
+
+        MY::postinstall( $pkg, $ver, $success ) if defined &MY::postinstall;
+    }
+
+    return $installed;
+}
+
+sub _has_cpanplus {
+    return (
+        $HasCPANPLUS = (
+            $INC{'CPANPLUS/Config.pm'}
+              or _load('CPANPLUS::Shell::Default')
+        )
+    );
+}
+
+# make guesses on whether we're under the CPAN installation directory
+sub _under_cpan {
+    require Cwd;
+    require File::Spec;
+
+    my $cwd  = File::Spec->canonpath( Cwd::cwd() );
+    my $cpan = File::Spec->canonpath( $CPAN::Config->{cpan_home} );
+
+    return ( index( $cwd, $cpan ) > -1 );
+}
+
+sub _update_to {
+    my $class = __PACKAGE__;
+    my $ver   = shift;
+
+    return
+      if defined( _version_check( _load($class), $ver ) );  # no need to upgrade
+
+    if (
+        _prompt( "==> A newer version of $class ($ver) is required. Install?",
+            'y' ) =~ /^[Nn]/
+      )
+    {
+        die "*** Please install $class $ver manually.\n";
+    }
+
+    print << ".";
+*** Trying to fetch it from CPAN...
+.
+
+    # install ourselves
+    _load($class) and return $class->import(@_)
+      if $class->install( [], $class, $ver );
+
+    print << '.'; exit 1;
+
+*** Cannot bootstrap myself. :-( Installation terminated.
+.
+}
+
+# check if we're connected to some host, using inet_aton
+sub _connected_to {
+    my $site = shift;
+
+    return (
+        ( _load('Socket') and Socket::inet_aton($site) ) or _prompt(
+            qq(
+*** Your host cannot resolve the domain name '$site', which
+    probably means the Internet connections are unavailable.
+==> Should we try to install the required module(s) anyway?), 'n'
+          ) =~ /^[Yy]/
+    );
+}
+
+# check if a directory is writable; may create it on demand
+sub _can_write {
+    my $path = shift;
+    mkdir( $path, 0755 ) unless -e $path;
+
+    return 1 if -w $path;
+
+    print << ".";
+*** You are not allowed to write to the directory '$path';
+    the installation may fail due to insufficient permissions.
+.
+
+    if (
+        eval '$>' and lc(`sudo -V`) =~ /version/ and _prompt(
+            qq(
+==> Should we try to re-execute the autoinstall process with 'sudo'?),
+            ((-t STDIN) ? 'y' : 'n')
+        ) =~ /^[Yy]/
+      )
+    {
+
+        # try to bootstrap ourselves from sudo
+        print << ".";
+*** Trying to re-execute the autoinstall process with 'sudo'...
+.
+        my $missing = join( ',', @Missing );
+        my $config = join( ',',
+            UNIVERSAL::isa( $Config, 'HASH' ) ? %{$Config} : @{$Config} )
+          if $Config;
+
+        return
+          unless system( 'sudo', $^X, $0, "--config=$config",
+            "--installdeps=$missing" );
+
+        print << ".";
+*** The 'sudo' command exited with error!  Resuming...
+.
+    }
+
+    return _prompt(
+        qq(
+==> Should we try to install the required module(s) anyway?), 'n'
+    ) =~ /^[Yy]/;
+}
+
+# load a module and return the version it reports
+sub _load {
+    my $mod  = pop;    # class/instance doesn't matter
+    my $file = $mod;
+
+    $file =~ s|::|/|g;
+    $file .= '.pm';
+
+    local $@;
+    return eval { require $file; $mod->VERSION } || ( $@ ? undef: 0 );
+}
+
+# Load CPAN.pm and it's configuration
+sub _load_cpan {
+    return if $CPAN::VERSION;
+    require CPAN;
+    if ( $CPAN::HandleConfig::VERSION ) {
+        # Newer versions of CPAN have a HandleConfig module
+        CPAN::HandleConfig->load;
+    } else {
+    	# Older versions had the load method in Config directly
+        CPAN::Config->load;
+    }
+}
+
+# compare two versions, either use Sort::Versions or plain comparison
+sub _version_check {
+    my ( $cur, $min ) = @_;
+    return unless defined $cur;
+
+    $cur =~ s/\s+$//;
+
+    # check for version numbers that are not in decimal format
+    if ( ref($cur) or ref($min) or $cur =~ /v|\..*\./ or $min =~ /v|\..*\./ ) {
+        if ( ( $version::VERSION or defined( _load('version') )) and
+             version->can('new') 
+            ) {
+
+            # use version.pm if it is installed.
+            return (
+                ( version->new($cur) >= version->new($min) ) ? $cur : undef );
+        }
+        elsif ( $Sort::Versions::VERSION or defined( _load('Sort::Versions') ) )
+        {
+
+            # use Sort::Versions as the sorting algorithm for a.b.c versions
+            return ( ( Sort::Versions::versioncmp( $cur, $min ) != -1 )
+                ? $cur
+                : undef );
+        }
+
+        warn "Cannot reliably compare non-decimal formatted versions.\n"
+          . "Please install version.pm or Sort::Versions.\n";
+    }
+
+    # plain comparison
+    local $^W = 0;    # shuts off 'not numeric' bugs
+    return ( $cur >= $min ? $cur : undef );
+}
+
+# nothing; this usage is deprecated.
+sub main::PREREQ_PM { return {}; }
+
+sub _make_args {
+    my %args = @_;
+
+    $args{PREREQ_PM} = { %{ $args{PREREQ_PM} || {} }, @Existing, @Missing }
+      if $UnderCPAN or $TestOnly;
+
+    if ( $args{EXE_FILES} and -e 'MANIFEST' ) {
+        require ExtUtils::Manifest;
+        my $manifest = ExtUtils::Manifest::maniread('MANIFEST');
+
+        $args{EXE_FILES} =
+          [ grep { exists $manifest->{$_} } @{ $args{EXE_FILES} } ];
+    }
+
+    $args{test}{TESTS} ||= 't/*.t';
+    $args{test}{TESTS} = join( ' ',
+        grep { !exists( $DisabledTests{$_} ) }
+          map { glob($_) } split( /\s+/, $args{test}{TESTS} ) );
+
+    my $missing = join( ',', @Missing );
+    my $config =
+      join( ',', UNIVERSAL::isa( $Config, 'HASH' ) ? %{$Config} : @{$Config} )
+      if $Config;
+
+    $PostambleActions = (
+        $missing
+        ? "\$(PERL) $0 --config=$config --installdeps=$missing"
+        : "\$(NOECHO) \$(NOOP)"
+    );
+
+    return %args;
+}
+
+# a wrapper to ExtUtils::MakeMaker::WriteMakefile
+sub Write {
+    require Carp;
+    Carp::croak "WriteMakefile: Need even number of args" if @_ % 2;
+
+    if ($CheckOnly) {
+        print << ".";
+*** Makefile not written in check-only mode.
+.
+        return;
+    }
+
+    my %args = _make_args(@_);
+
+    no strict 'refs';
+
+    $PostambleUsed = 0;
+    local *MY::postamble = \&postamble unless defined &MY::postamble;
+    ExtUtils::MakeMaker::WriteMakefile(%args);
+
+    print << "." unless $PostambleUsed;
+*** WARNING: Makefile written with customized MY::postamble() without
+    including contents from Module::AutoInstall::postamble() --
+    auto installation features disabled.  Please contact the author.
+.
+
+    return 1;
+}
+
+sub postamble {
+    $PostambleUsed = 1;
+
+    return << ".";
+
+config :: installdeps
+\t\$(NOECHO) \$(NOOP)
+
+checkdeps ::
+\t\$(PERL) $0 --checkdeps
+
+installdeps ::
+\t$PostambleActions
+
+.
+
+}
+
+1;
+
+__END__
+
+#line 1003
diff --git a/inc/Module/Install/AutoInstall.pm b/inc/Module/Install/AutoInstall.pm
new file mode 100644
index 0000000..ce24f7e
--- /dev/null
+++ b/inc/Module/Install/AutoInstall.pm
@@ -0,0 +1,61 @@
+#line 1
+package Module::Install::AutoInstall;
+
+use strict;
+use Module::Install::Base;
+
+use vars qw{$VERSION $ISCORE @ISA};
+BEGIN {
+	$VERSION = '0.72';
+	$ISCORE  = 1;
+	@ISA     = qw{Module::Install::Base};
+}
+
+sub AutoInstall { $_[0] }
+
+sub run {
+    my $self = shift;
+    $self->auto_install_now(@_);
+}
+
+sub write {
+    my $self = shift;
+    $self->auto_install(@_);
+}
+
+sub auto_install {
+    my $self = shift;
+    return if $self->{done}++;
+
+    # Flatten array of arrays into a single array
+    my @core = map @$_, map @$_, grep ref,
+               $self->build_requires, $self->requires;
+
+    my @config = @_;
+
+    # We'll need Module::AutoInstall
+    $self->include('Module::AutoInstall');
+    require Module::AutoInstall;
+
+    Module::AutoInstall->import(
+        (@config ? (-config => \@config) : ()),
+        (@core   ? (-core   => \@core)   : ()),
+        $self->features,
+    );
+
+    $self->makemaker_args( Module::AutoInstall::_make_args() );
+
+    my $class = ref($self);
+    $self->postamble(
+        "# --- $class section:\n" .
+        Module::AutoInstall::postamble()
+    );
+}
+
+sub auto_install_now {
+    my $self = shift;
+    $self->auto_install(@_);
+    Module::AutoInstall::do_install();
+}
+
+1;
diff --git a/inc/Module/Install/Can.pm b/inc/Module/Install/Can.pm
new file mode 100644
index 0000000..ea669c2
--- /dev/null
+++ b/inc/Module/Install/Can.pm
@@ -0,0 +1,82 @@
+#line 1
+package Module::Install::Can;
+
+use strict;
+use Module::Install::Base;
+use Config ();
+### This adds a 5.005 Perl version dependency.
+### This is a bug and will be fixed.
+use File::Spec ();
+use ExtUtils::MakeMaker ();
+
+use vars qw{$VERSION $ISCORE @ISA};
+BEGIN {
+	$VERSION = '0.72';
+	$ISCORE  = 1;
+	@ISA     = qw{Module::Install::Base};
+}
+
+# check if we can load some module
+### Upgrade this to not have to load the module if possible
+sub can_use {
+	my ($self, $mod, $ver) = @_;
+	$mod =~ s{::|\\}{/}g;
+	$mod .= '.pm' unless $mod =~ /\.pm$/i;
+
+	my $pkg = $mod;
+	$pkg =~ s{/}{::}g;
+	$pkg =~ s{\.pm$}{}i;
+
+	local $@;
+	eval { require $mod; $pkg->VERSION($ver || 0); 1 };
+}
+
+# check if we can run some command
+sub can_run {
+	my ($self, $cmd) = @_;
+
+	my $_cmd = $cmd;
+	return $_cmd if (-x $_cmd or $_cmd = MM->maybe_command($_cmd));
+
+	for my $dir ((split /$Config::Config{path_sep}/, $ENV{PATH}), '.') {
+		my $abs = File::Spec->catfile($dir, $_[1]);
+		return $abs if (-x $abs or $abs = MM->maybe_command($abs));
+	}
+
+	return;
+}
+
+# can we locate a (the) C compiler
+sub can_cc {
+	my $self   = shift;
+	my @chunks = split(/ /, $Config::Config{cc}) or return;
+
+	# $Config{cc} may contain args; try to find out the program part
+	while (@chunks) {
+		return $self->can_run("@chunks") || (pop(@chunks), next);
+	}
+
+	return;
+}
+
+# Fix Cygwin bug on maybe_command();
+if ( $^O eq 'cygwin' ) {
+	require ExtUtils::MM_Cygwin;
+	require ExtUtils::MM_Win32;
+	if ( ! defined(&ExtUtils::MM_Cygwin::maybe_command) ) {
+		*ExtUtils::MM_Cygwin::maybe_command = sub {
+			my ($self, $file) = @_;
+			if ($file =~ m{^/cygdrive/}i and ExtUtils::MM_Win32->can('maybe_command')) {
+				ExtUtils::MM_Win32->maybe_command($file);
+			} else {
+				ExtUtils::MM_Unix->maybe_command($file);
+			}
+		}
+	}
+}
+
+1;
+
+__END__
+
+#line 157
diff --git a/inc/Module/Install/Fetch.pm b/inc/Module/Install/Fetch.pm
new file mode 100644
index 0000000..e283757
--- /dev/null
+++ b/inc/Module/Install/Fetch.pm
@@ -0,0 +1,93 @@
+#line 1
+package Module::Install::Fetch;
+
+use strict;
+use Module::Install::Base;
+
+use vars qw{$VERSION $ISCORE @ISA};
+BEGIN {
+	$VERSION = '0.72';
+	$ISCORE  = 1;
+	@ISA     = qw{Module::Install::Base};
+}
+
+sub get_file {
+    my ($self, %args) = @_;
+    my ($scheme, $host, $path, $file) = 
+        $args{url} =~ m|^(\w+)://([^/]+)(.+)/(.+)| or return;
+
+    if ( $scheme eq 'http' and ! eval { require LWP::Simple; 1 } ) {
+        $args{url} = $args{ftp_url}
+            or (warn("LWP support unavailable!\n"), return);
+        ($scheme, $host, $path, $file) = 
+            $args{url} =~ m|^(\w+)://([^/]+)(.+)/(.+)| or return;
+    }
+
+    $|++;
+    print "Fetching '$file' from $host... ";
+
+    unless (eval { require Socket; Socket::inet_aton($host) }) {
+        warn "'$host' resolve failed!\n";
+        return;
+    }
+
+    return unless $scheme eq 'ftp' or $scheme eq 'http';
+
+    require Cwd;
+    my $dir = Cwd::getcwd();
+    chdir $args{local_dir} or return if exists $args{local_dir};
+
+    if (eval { require LWP::Simple; 1 }) {
+        LWP::Simple::mirror($args{url}, $file);
+    }
+    elsif (eval { require Net::FTP; 1 }) { eval {
+        # use Net::FTP to get past firewall
+        my $ftp = Net::FTP->new($host, Passive => 1, Timeout => 600);
+        $ftp->login("anonymous", 'anonymous at example.com');
+        $ftp->cwd($path);
+        $ftp->binary;
+        $ftp->get($file) or (warn("$!\n"), return);
+        $ftp->quit;
+    } }
+    elsif (my $ftp = $self->can_run('ftp')) { eval {
+        # no Net::FTP, fallback to ftp.exe
+        require FileHandle;
+        my $fh = FileHandle->new;
+
+        local $SIG{CHLD} = 'IGNORE';
+        unless ($fh->open("|$ftp -n")) {
+            warn "Couldn't open ftp: $!\n";
+            chdir $dir; return;
+        }
+
+        my @dialog = split(/\n/, <<"END_FTP");
+open $host
+user anonymous anonymous\@example.com
+cd $path
+binary
+get $file $file
+quit
+END_FTP
+        foreach (@dialog) { $fh->print("$_\n") }
+        $fh->close;
+    } }
+    else {
+        warn "No working 'ftp' program available!\n";
+        chdir $dir; return;
+    }
+
+    unless (-f $file) {
+        warn "Fetching failed: $@\n";
+        chdir $dir; return;
+    }
+
+    return if exists $args{size} and -s $file != $args{size};
+    system($args{run}) if exists $args{run};
+    unlink($file) if $args{remove};
+
+    print(((!exists $args{check_for} or -e $args{check_for})
+        ? "done!" : "failed! ($!)"), "\n");
+    chdir $dir; return !$?;
+}
+
+1;
diff --git a/inc/Module/Install/Include.pm b/inc/Module/Install/Include.pm
new file mode 100644
index 0000000..d27a92a
--- /dev/null
+++ b/inc/Module/Install/Include.pm
@@ -0,0 +1,34 @@
+#line 1
+package Module::Install::Include;
+
+use strict;
+use Module::Install::Base;
+
+use vars qw{$VERSION $ISCORE @ISA};
+BEGIN {
+	$VERSION = '0.72';
+	$ISCORE  = 1;
+	@ISA     = qw{Module::Install::Base};
+}
+
+sub include {
+	shift()->admin->include(@_);
+}
+
+sub include_deps {
+	shift()->admin->include_deps(@_);
+}
+
+sub auto_include {
+	shift()->admin->auto_include(@_);
+}
+
+sub auto_include_deps {
+	shift()->admin->auto_include_deps(@_);
+}
+
+sub auto_include_dependent_dists {
+	shift()->admin->auto_include_dependent_dists(@_);
+}
+
+1;
diff --git a/inc/Module/Install/RTx.pm b/inc/Module/Install/RTx.pm
index c087b12..80a8b5c 100644
--- a/inc/Module/Install/RTx.pm
+++ b/inc/Module/Install/RTx.pm
@@ -8,7 +8,7 @@ no warnings 'once';
 
 use Module::Install::Base;
 use base 'Module::Install::Base';
-our $VERSION = '0.22';
+our $VERSION = '0.23';
 
 use FindBin;
 use File::Glob     ();
diff --git a/inc/Module/Install/Win32.pm b/inc/Module/Install/Win32.pm
new file mode 100644
index 0000000..f8744e7
--- /dev/null
+++ b/inc/Module/Install/Win32.pm
@@ -0,0 +1,64 @@
+#line 1
+package Module::Install::Win32;
+
+use strict;
+use Module::Install::Base;
+
+use vars qw{$VERSION @ISA $ISCORE};
+BEGIN {
+	$VERSION = '0.72';
+	@ISA     = qw{Module::Install::Base};
+	$ISCORE  = 1;
+}
+
+# determine if the user needs nmake, and download it if needed
+sub check_nmake {
+	my $self = shift;
+	$self->load('can_run');
+	$self->load('get_file');
+
+	require Config;
+	return unless (
+		$^O eq 'MSWin32'                     and
+		$Config::Config{make}                and
+		$Config::Config{make} =~ /^nmake\b/i and
+		! $self->can_run('nmake')
+	);
+
+	print "The required 'nmake' executable not found, fetching it...\n";
+
+	require File::Basename;
+	my $rv = $self->get_file(
+		url       => 'http://download.microsoft.com/download/vc15/Patch/1.52/W95/EN-US/Nmake15.exe',
+		ftp_url   => 'ftp://ftp.microsoft.com/Softlib/MSLFILES/Nmake15.exe',
+		local_dir => File::Basename::dirname($^X),
+		size      => 51928,
+		run       => 'Nmake15.exe /o > nul',
+		check_for => 'Nmake.exe',
+		remove    => 1,
+	);
+
+	die <<'END_MESSAGE' unless $rv;
+
+-------------------------------------------------------------------------------
+
+Since you are using Microsoft Windows, you will need the 'nmake' utility
+before installation. It's available at:
+
+  http://download.microsoft.com/download/vc15/Patch/1.52/W95/EN-US/Nmake15.exe
+      or
+  ftp://ftp.microsoft.com/Softlib/MSLFILES/Nmake15.exe
+
+Please download the file manually, save it to a directory in %PATH% (e.g.
+C:\WINDOWS\COMMAND\), then launch the MS-DOS command line shell, "cd" to
+that directory, and run "Nmake15.exe" from there; that will create the
+'nmake.exe' file needed by this module.
+
+You may then resume the installation process described in README.
+
+-------------------------------------------------------------------------------
+END_MESSAGE
+
+}
+
+1;
diff --git a/inc/Module/Install/WriteAll.pm b/inc/Module/Install/WriteAll.pm
new file mode 100644
index 0000000..d1d8a06
--- /dev/null
+++ b/inc/Module/Install/WriteAll.pm
@@ -0,0 +1,40 @@
+#line 1
+package Module::Install::WriteAll;
+
+use strict;
+use Module::Install::Base;
+
+use vars qw{$VERSION @ISA $ISCORE};
+BEGIN {
+	$VERSION = '0.72';
+	@ISA     = qw{Module::Install::Base};
+	$ISCORE  = 1;
+}
+
+sub WriteAll {
+	my $self = shift;
+	my %args = (
+		meta        => 1,
+		sign        => 0,
+		inline      => 0,
+		check_nmake => 1,
+		@_,
+	);
+
+	$self->sign(1)                if $args{sign};
+	$self->Meta->write            if $args{meta};
+	$self->admin->WriteAll(%args) if $self->is_admin;
+
+	$self->check_nmake if $args{check_nmake};
+	unless ( $self->makemaker_args->{PL_FILES} ) {
+		$self->makemaker_args( PL_FILES => {} );
+	}
+
+	if ( $args{inline} ) {
+		$self->Inline->write;
+	} else {
+		$self->Makefile->write;
+	}
+}
+
+1;
diff --git a/lib/RTFM/Extension/ArticleTemplates.pm b/lib/RTFM/Extension/ArticleTemplates.pm
index f77ae4e..a9518a9 100644
--- a/lib/RTFM/Extension/ArticleTemplates.pm
+++ b/lib/RTFM/Extension/ArticleTemplates.pm
@@ -2,12 +2,14 @@ package RTFM::Extension::ArticleTemplates;
 
 our $VERSION = '0.01';
 
+use 5.8.3;
 use strict;
 use warnings;
 
+
 =head1 NAME
 
-RTFM::Extension::ArticleTemplates - turns articles' custom fields into templates.
+RTFM::Extension::ArticleTemplates - turns articles into dynamic templates.
 
 =head1 DESCRIPTION
 
@@ -37,8 +39,8 @@ commands:
 
 =head1 AUTHOR
 
-Kevin Falcone  C<< <falcone at bestpractical.com> >>
-Ruslan Zakirov C<< <ruz at bestpractical.com> >>
+Kevin Falcone E<lt>falcone at bestpractical.comE<gt>
+Ruslan Zakirov E<lt>ruz at bestpractical.comE<gt>
 
 =head1 LICENCE AND COPYRIGHT
 

commit 5b7406838bb7a2e3bdb1701f0bc9d48662b84151
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Mon May 12 22:40:45 2008 +0000

    update meanifest
    update changelog

diff --git a/Changes b/Changes
index 785f2d1..0b67e80 100644
--- a/Changes
+++ b/Changes
@@ -1,5 +1,5 @@
 Revision history for RTFM-Extension-ArticleTemplates
 
-0.01  Fri May  9 14:51:44 2008
+0.01  Tue May 13 2008
        Initial release.
 
diff --git a/MANIFEST b/MANIFEST
index 7785679..419105c 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1,8 +1,23 @@
 Changes
-MANIFEST
+html/Callbacks/RTFM-Extension-ArticleTemplates/RTFM/Article/Elements/Preformatted/ProcessContent
+inc/Module/AutoInstall.pm
+inc/Module/Install.pm
+inc/Module/Install/AutoInstall.pm
+inc/Module/Install/Base.pm
+inc/Module/Install/Can.pm
+inc/Module/Install/Fetch.pm
+inc/Module/Install/Include.pm
+inc/Module/Install/Makefile.pm
+inc/Module/Install/Metadata.pm
+inc/Module/Install/RTx.pm
+inc/Module/Install/Win32.pm
+inc/Module/Install/WriteAll.pm
+lib/RT/FM/Article_Local.pm
+lib/RTFM/Extension/ArticleTemplates.pm
 Makefile.PL
+MANIFEST
+META.yml
 README
-lib/RTFM/Extension/ArticleTemplates.pm
 t/00.load.t
 t/pod-coverage.t
 t/pod.t

commit 30d635866e22ef948532526907f222891d6b1848
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Mon Sep 15 23:17:47 2008 +0000

    update installer
    bump version

diff --git a/Changes b/Changes
index 0b67e80..ac67624 100644
--- a/Changes
+++ b/Changes
@@ -1,5 +1,10 @@
 Revision history for RTFM-Extension-ArticleTemplates
 
+0.02  Mon Sep 15 2008
+
+    Update installer.
+
 0.01  Tue May 13 2008
-       Initial release.
+
+    Initial release.
 
diff --git a/META.yml b/META.yml
index a133b74..4debdd6 100644
--- a/META.yml
+++ b/META.yml
@@ -5,18 +5,20 @@ author:
 build_requires:
   Test::More: 0
 distribution_type: module
-generated_by: 'Module::Install version 0.72'
+generated_by: 'Module::Install version 0.77'
 license: 'GPL version 2'
 meta-spec:
-  url: http://module-build.sourceforge.net/META-spec-v1.3.html
-  version: 1.3
+  url: http://module-build.sourceforge.net/META-spec-v1.4.html
+  version: 1.4
 name: RTFM-Extension-ArticleTemplates
 no_index:
   directory:
+    - etc
     - html
+    - po
+    - var
     - inc
     - t
 requires:
-  RT::FM: 2.2.2
   perl: 5.8.3
-version: 0.01
+version: 0.02
diff --git a/Makefile.PL b/Makefile.PL
index 82613f7..12fddc4 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -10,7 +10,8 @@ my ($lib_path) = $INC{'RT.pm'} =~ /^(.*)[\\\/]/;
 my $local_lib_path = "$RT::LocalPath/lib";
 
 unshift @INC, $local_lib_path, $lib_path;
-requires('RT::FM' => '2.2.2');
+# XXX: Cannot depend on RT::FM with new plugins subsystem
+#requires('RT::FM' => '2.2.2');
 
 auto_install;
 
diff --git a/inc/Module/Install.pm b/inc/Module/Install.pm
index 052cf1e..eb449ca 100644
--- a/inc/Module/Install.pm
+++ b/inc/Module/Install.pm
@@ -30,7 +30,7 @@ BEGIN {
 	# This is not enforced yet, but will be some time in the next few
 	# releases once we can make sure it won't clash with custom
 	# Module::Install extensions.
-	$VERSION = '0.72';
+	$VERSION = '0.77';
 
 	*inc::Module::Install::VERSION = *VERSION;
 	@inc::Module::Install::ISA     = __PACKAGE__;
@@ -85,7 +85,7 @@ END_DIE
 
 # Build.PL was formerly supported, but no longer is due to excessive
 # difficulty in implementing every single feature twice.
-if ( $0 =~ /Build.PL$/i or -f 'Build.PL' ) { die <<"END_DIE" }
+if ( $0 =~ /Build.PL$/i ) { die <<"END_DIE" }
 
 Module::Install no longer supports Build.PL.
 
@@ -125,8 +125,10 @@ sub autoload {
 			goto &$code unless $cwd eq $pwd;
 		}
 		$$sym =~ /([^:]+)$/ or die "Cannot autoload $who - $sym";
-		unshift @_, ( $self, $1 );
-		goto &{$self->can('call')} unless uc($1) eq $1;
+		unless ( uc($1) eq $1 ) {
+			unshift @_, ( $self, $1 );
+			goto &{$self->can('call')};
+		}
 	};
 }
 
@@ -339,7 +341,10 @@ sub _write {
 	close FH or die "close($_[0]): $!";
 }
 
-sub _version {
+# _version is for processing module versions (eg, 1.03_05) not
+# Perl versions (eg, 5.8.1).
+
+sub _version ($) {
 	my $s = shift || 0;
 	   $s =~ s/^(\d+)\.?//;
 	my $l = $1 || 0;
@@ -348,6 +353,17 @@ sub _version {
 	return $l + 0;
 }
 
+# Cloned from Params::Util::_CLASS
+sub _CLASS ($) {
+	(
+		defined $_[0]
+		and
+		! ref $_[0]
+		and
+		$_[0] =~ m/^[^\W\d]\w*(?:::\w+)*$/s
+	) ? $_[0] : undef;
+}
+
 1;
 
 # Copyright 2008 Adam Kennedy.
diff --git a/inc/Module/Install/AutoInstall.pm b/inc/Module/Install/AutoInstall.pm
index ce24f7e..8b3bcaa 100644
--- a/inc/Module/Install/AutoInstall.pm
+++ b/inc/Module/Install/AutoInstall.pm
@@ -6,7 +6,7 @@ use Module::Install::Base;
 
 use vars qw{$VERSION $ISCORE @ISA};
 BEGIN {
-	$VERSION = '0.72';
+	$VERSION = '0.77';
 	$ISCORE  = 1;
 	@ISA     = qw{Module::Install::Base};
 }
diff --git a/inc/Module/Install/Base.pm b/inc/Module/Install/Base.pm
index 7fd0189..433ebed 100644
--- a/inc/Module/Install/Base.pm
+++ b/inc/Module/Install/Base.pm
@@ -1,7 +1,7 @@
 #line 1
 package Module::Install::Base;
 
-$VERSION = '0.72';
+$VERSION = '0.77';
 
 # Suspend handler for "redefined" warnings
 BEGIN {
@@ -45,6 +45,8 @@ sub admin {
     $_[0]->_top->{admin} or Module::Install::Base::FakeAdmin->new;
 }
 
+#line 101
+
 sub is_admin {
     $_[0]->admin->VERSION;
 }
@@ -67,4 +69,4 @@ BEGIN {
 
 1;
 
-#line 138
+#line 146
diff --git a/inc/Module/Install/Can.pm b/inc/Module/Install/Can.pm
index ea669c2..9025607 100644
--- a/inc/Module/Install/Can.pm
+++ b/inc/Module/Install/Can.pm
@@ -11,7 +11,7 @@ use ExtUtils::MakeMaker ();
 
 use vars qw{$VERSION $ISCORE @ISA};
 BEGIN {
-	$VERSION = '0.72';
+	$VERSION = '0.77';
 	$ISCORE  = 1;
 	@ISA     = qw{Module::Install::Base};
 }
@@ -39,6 +39,7 @@ sub can_run {
 	return $_cmd if (-x $_cmd or $_cmd = MM->maybe_command($_cmd));
 
 	for my $dir ((split /$Config::Config{path_sep}/, $ENV{PATH}), '.') {
+		next if $dir eq '';
 		my $abs = File::Spec->catfile($dir, $_[1]);
 		return $abs if (-x $abs or $abs = MM->maybe_command($abs));
 	}
@@ -79,4 +80,4 @@ if ( $^O eq 'cygwin' ) {
 
 __END__
 
-#line 157
+#line 158
diff --git a/inc/Module/Install/Fetch.pm b/inc/Module/Install/Fetch.pm
index e283757..d66aba5 100644
--- a/inc/Module/Install/Fetch.pm
+++ b/inc/Module/Install/Fetch.pm
@@ -6,7 +6,7 @@ use Module::Install::Base;
 
 use vars qw{$VERSION $ISCORE @ISA};
 BEGIN {
-	$VERSION = '0.72';
+	$VERSION = '0.77';
 	$ISCORE  = 1;
 	@ISA     = qw{Module::Install::Base};
 }
diff --git a/inc/Module/Install/Include.pm b/inc/Module/Install/Include.pm
index d27a92a..0c7dc5a 100644
--- a/inc/Module/Install/Include.pm
+++ b/inc/Module/Install/Include.pm
@@ -6,7 +6,7 @@ use Module::Install::Base;
 
 use vars qw{$VERSION $ISCORE @ISA};
 BEGIN {
-	$VERSION = '0.72';
+	$VERSION = '0.77';
 	$ISCORE  = 1;
 	@ISA     = qw{Module::Install::Base};
 }
diff --git a/inc/Module/Install/Makefile.pm b/inc/Module/Install/Makefile.pm
index f40a97c..92cd1ef 100644
--- a/inc/Module/Install/Makefile.pm
+++ b/inc/Module/Install/Makefile.pm
@@ -7,7 +7,7 @@ use ExtUtils::MakeMaker ();
 
 use vars qw{$VERSION $ISCORE @ISA};
 BEGIN {
-	$VERSION = '0.72';
+	$VERSION = '0.77';
 	$ISCORE  = 1;
 	@ISA     = qw{Module::Install::Base};
 }
@@ -36,9 +36,9 @@ sub prompt {
 
 sub makemaker_args {
 	my $self = shift;
-	my $args = ($self->{makemaker_args} ||= {});
-	  %$args = ( %$args, @_ ) if @_;
-	$args;
+	my $args = ( $self->{makemaker_args} ||= {} );
+	%$args = ( %$args, @_ );
+	return $args;
 }
 
 # For mm args that take multiple space-seperated args,
@@ -116,7 +116,13 @@ sub write {
 
 	# Make sure we have a new enough
 	require ExtUtils::MakeMaker;
-	$self->configure_requires( 'ExtUtils::MakeMaker' => $ExtUtils::MakeMaker::VERSION );
+
+	# MakeMaker can complain about module versions that include
+	# an underscore, even though its own version may contain one!
+	# Hence the funny regexp to get rid of it.  See RT #35800
+	# for details.
+
+	$self->configure_requires( 'ExtUtils::MakeMaker' => $ExtUtils::MakeMaker::VERSION =~ /^(\d+\.\d+)/ );
 
 	# Generate the 
 	my $args = $self->makemaker_args;
@@ -175,7 +181,9 @@ sub write {
 
 	my $user_preop = delete $args{dist}->{PREOP};
 	if (my $preop = $self->admin->preop($user_preop)) {
-		$args{dist} = $preop;
+		foreach my $key ( keys %$preop ) {
+			$args{dist}->{$key} = $preop->{$key};
+		}
 	}
 
 	my $mm = ExtUtils::MakeMaker::WriteMakefile(%args);
@@ -242,4 +250,4 @@ sub postamble {
 
 __END__
 
-#line 371
+#line 379
diff --git a/inc/Module/Install/Metadata.pm b/inc/Module/Install/Metadata.pm
index a10c773..397fb97 100644
--- a/inc/Module/Install/Metadata.pm
+++ b/inc/Module/Install/Metadata.pm
@@ -6,7 +6,7 @@ use Module::Install::Base;
 
 use vars qw{$VERSION $ISCORE @ISA};
 BEGIN {
-	$VERSION = '0.72';
+	$VERSION = '0.77';
 	$ISCORE  = 1;
 	@ISA     = qw{Module::Install::Base};
 }
@@ -17,9 +17,7 @@ my @scalar_keys = qw{
 	abstract
 	author
 	version
-	license
 	distribution_type
-	perl_version
 	tests
 	installdirs
 };
@@ -30,13 +28,21 @@ my @tuple_keys = qw{
 	requires
 	recommends
 	bundles
+	resources
+};
+
+my @resource_keys = qw{
+	homepage
+	bugtracker
+	repository
 };
 
-sub Meta            { shift        }
-sub Meta_ScalarKeys { @scalar_keys }
-sub Meta_TupleKeys  { @tuple_keys  }
+sub Meta              { shift          }
+sub Meta_ScalarKeys   { @scalar_keys   }
+sub Meta_TupleKeys    { @tuple_keys    }
+sub Meta_ResourceKeys { @resource_keys }
 
-foreach my $key (@scalar_keys) {
+foreach my $key ( @scalar_keys ) {
 	*$key = sub {
 		my $self = shift;
 		return $self->{values}{$key} if defined wantarray and !@_;
@@ -45,12 +51,30 @@ foreach my $key (@scalar_keys) {
 	};
 }
 
+foreach my $key ( @resource_keys ) {
+	*$key = sub {
+		my $self = shift;
+		unless ( @_ ) {
+			return () unless $self->{values}{resources};
+			return map  { $_->[1] }
+			       grep { $_->[0] eq $key }
+			       @{ $self->{values}{resources} };
+		}
+		return $self->{values}{resources}{$key} unless @_;
+		my $uri = shift or die(
+			"Did not provide a value to $key()"
+		);
+		$self->resources( $key => $uri );
+		return 1;
+	};
+}
+
 sub requires {
 	my $self = shift;
 	while ( @_ ) {
 		my $module  = shift or last;
 		my $version = shift || 0;
-		push @{ $self->{values}->{requires} }, [ $module, $version ];
+		push @{ $self->{values}{requires} }, [ $module, $version ];
 	}
 	$self->{values}{requires};
 }
@@ -60,7 +84,7 @@ sub build_requires {
 	while ( @_ ) {
 		my $module  = shift or last;
 		my $version = shift || 0;
-		push @{ $self->{values}->{build_requires} }, [ $module, $version ];
+		push @{ $self->{values}{build_requires} }, [ $module, $version ];
 	}
 	$self->{values}{build_requires};
 }
@@ -70,7 +94,7 @@ sub configure_requires {
 	while ( @_ ) {
 		my $module  = shift or last;
 		my $version = shift || 0;
-		push @{ $self->{values}->{configure_requires} }, [ $module, $version ];
+		push @{ $self->{values}{configure_requires} }, [ $module, $version ];
 	}
 	$self->{values}{configure_requires};
 }
@@ -80,7 +104,7 @@ sub recommends {
 	while ( @_ ) {
 		my $module  = shift or last;
 		my $version = shift || 0;
-		push @{ $self->{values}->{recommends} }, [ $module, $version ];
+		push @{ $self->{values}{recommends} }, [ $module, $version ];
 	}
 	$self->{values}{recommends};
 }
@@ -90,11 +114,33 @@ sub bundles {
 	while ( @_ ) {
 		my $module  = shift or last;
 		my $version = shift || 0;
-		push @{ $self->{values}->{bundles} }, [ $module, $version ];
+		push @{ $self->{values}{bundles} }, [ $module, $version ];
 	}
 	$self->{values}{bundles};
 }
 
+# Resource handling
+my %lc_resource = map { $_ => 1 } qw{
+	homepage
+	license
+	bugtracker
+	repository
+};
+
+sub resources {
+	my $self = shift;
+	while ( @_ ) {
+		my $name  = shift or last;
+		my $value = shift or next;
+		if ( $name eq lc $name and ! $lc_resource{$name} ) {
+			die("Unsupported reserved lowercase resource '$name'");
+		}
+		$self->{values}{resources} ||= [];
+		push @{ $self->{values}{resources} }, [ $name, $value ];
+	}
+	$self->{values}{resources};
+}
+
 # Aliases for build_requires that will have alternative
 # meanings in some future version of META.yml.
 sub test_requires      { shift->build_requires(@_) }
@@ -108,30 +154,73 @@ sub install_as_vendor  { $_[0]->installdirs('vendor') }
 
 sub sign {
 	my $self = shift;
-	return $self->{'values'}{'sign'} if defined wantarray and ! @_;
-	$self->{'values'}{'sign'} = ( @_ ? $_[0] : 1 );
+	return $self->{values}{sign} if defined wantarray and ! @_;
+	$self->{values}{sign} = ( @_ ? $_[0] : 1 );
 	return $self;
 }
 
 sub dynamic_config {
 	my $self = shift;
 	unless ( @_ ) {
-		warn "You MUST provide an explicit true/false value to dynamic_config, skipping\n";
+		warn "You MUST provide an explicit true/false value to dynamic_config\n";
 		return $self;
 	}
 	$self->{values}{dynamic_config} = $_[0] ? 1 : 0;
-	return $self;
+	return 1;
+}
+
+sub perl_version {
+	my $self = shift;
+	return $self->{values}{perl_version} unless @_;
+	my $version = shift or die(
+		"Did not provide a value to perl_version()"
+	);
+
+	# Convert triple-part versions (eg, 5.6.1 or 5.8.9) to
+	# numbers (eg, 5.006001 or 5.008009).
+
+	$version =~ s/^(\d+)\.(\d+)\.(\d+)$/sprintf("%d.%03d%03d",$1,$2,$3)/e;
+
+	$version =~ s/_.+$//;
+	$version = $version + 0; # Numify
+	unless ( $version >= 5.005 ) {
+		die "Module::Install only supports 5.005 or newer (use ExtUtils::MakeMaker)\n";
+	}
+	$self->{values}{perl_version} = $version;
+	return 1;
+}
+
+sub license {
+	my $self = shift;
+	return $self->{values}{license} unless @_;
+	my $license = shift or die(
+		'Did not provide a value to license()'
+	);
+	$self->{values}{license} = $license;
+
+	# Automatically fill in license URLs
+	if ( $license eq 'perl' ) {
+		$self->resources( license => 'http://dev.perl.org/licenses/' );
+	}
+
+	return 1;
 }
 
 sub all_from {
 	my ( $self, $file ) = @_;
 
 	unless ( defined($file) ) {
-		my $name = $self->name
-			or die "all_from called with no args without setting name() first";
+		my $name = $self->name or die(
+			"all_from called with no args without setting name() first"
+		);
 		$file = join('/', 'lib', split(/-/, $name)) . '.pm';
 		$file =~ s{.*/}{} unless -e $file;
-		die "all_from: cannot find $file from $name" unless -e $file;
+		unless ( -e $file ) {
+			die("all_from cannot find $file from $name");
+		}
+	}
+	unless ( -f $file ) {
+		die("The path '$file' does not exist, or is not a file");
 	}
 
 	# Some methods pull from POD instead of code.
@@ -210,8 +299,8 @@ sub features {
 	while ( my ( $name, $mods ) = splice( @_, 0, 2 ) ) {
 		$self->feature( $name, @$mods );
 	}
-	return $self->{values}->{features}
-		? @{ $self->{values}->{features} }
+	return $self->{values}{features}
+		? @{ $self->{values}{features} }
 		: ();
 }
 
@@ -267,22 +356,25 @@ sub abstract_from {
 	 );
 }
 
+# Add both distribution and module name
 sub name_from {
-	my $self = shift;
+	my ($self, $file) = @_;
 	if (
-		Module::Install::_read($_[0]) =~ m/
+		Module::Install::_read($file) =~ m/
 		^ \s*
 		package \s*
 		([\w:]+)
 		\s* ;
 		/ixms
 	) {
-		my $name = $1;
+		my ($name, $module_name) = ($1, $1);
 		$name =~ s{::}{-}g;
 		$self->name($name);
+		unless ( $self->module_name ) {
+			$self->module_name($module_name);
+		}
 	} else {
-		die "Cannot determine name from $_[0]\n";
-		return;
+		die("Cannot determine name from $file\n");
 	}
 }
 
@@ -291,7 +383,7 @@ sub perl_version_from {
 	if (
 		Module::Install::_read($_[0]) =~ m/
 		^
-		use \s*
+		(?:use|require) \s*
 		v?
 		([\d_\.]+)
 		\s* ;
@@ -341,8 +433,12 @@ sub license_from {
 		my $license_text = $1;
 		my @phrases      = (
 			'under the same (?:terms|license) as perl itself' => 'perl',        1,
+			'GNU general public license'                      => 'gpl',         1,
 			'GNU public license'                              => 'gpl',         1,
+			'GNU lesser general public license'               => 'lgpl',        1,
 			'GNU lesser public license'                       => 'lgpl',        1,
+			'GNU library general public license'              => 'lgpl',        1,
+			'GNU library public license'                      => 'lgpl',        1,
 			'BSD license'                                     => 'bsd',         1,
 			'Artistic license'                                => 'artistic',    1,
 			'GPL'                                             => 'gpl',         1,
@@ -356,7 +452,7 @@ sub license_from {
 			$pattern =~ s{\s+}{\\s+}g;
 			if ( $license_text =~ /\b$pattern\b/i ) {
 				if ( $osi and $license_text =~ /All rights reserved/i ) {
-					warn "LEGAL WARNING: 'All rights reserved' may invalidate Open Source licenses. Consider removing it.";
+					print "WARNING: 'All rights reserved' in copyright may invalidate Open Source license.\n";
 				}
 				$self->license($license);
 				return 1;
@@ -368,6 +464,24 @@ sub license_from {
 	return 'unknown';
 }
 
+sub bugtracker_from {
+	my $self    = shift;
+	my $content = Module::Install::_read($_[0]);
+	my @links   = $content =~ m/L\<(http\:\/\/rt\.cpan\.org\/[^>]+)\>/g;
+	unless ( @links ) {
+		warn "Cannot determine bugtracker info from $_[0]\n";
+		return 0;
+	}
+	if ( @links > 1 ) {
+		warn "Found more than on rt.cpan.org link in $_[0]\n";
+		return 0;
+	}
+
+	# Set the bugtracker
+	bugtracker( $links[0] );
+	return 1;
+}
+
 sub install_script {
 	my $self = shift;
 	my $args = $self->makemaker_args;
@@ -378,7 +492,7 @@ sub install_script {
 		} elsif ( -d 'script' and -f "script/$_" ) {
 			push @$exe, "script/$_";
 		} else {
-			die "Cannot find script '$_'";
+			die("Cannot find script '$_'");
 		}
 	}
 }
diff --git a/inc/Module/Install/RTx.pm b/inc/Module/Install/RTx.pm
index 80a8b5c..2028f5e 100644
--- a/inc/Module/Install/RTx.pm
+++ b/inc/Module/Install/RTx.pm
@@ -14,6 +14,9 @@ use FindBin;
 use File::Glob     ();
 use File::Basename ();
 
+my @DIRS = qw(etc lib html bin sbin po var);
+my @INDEX_DIRS = qw(lib bin sbin);
+
 sub RTx {
     my ( $self, $name ) = @_;
 
@@ -60,8 +63,8 @@ sub RTx {
     $RT::LocalVarPath  ||= $RT::VarPath;
     $RT::LocalPoPath   ||= $RT::LocalLexiconPath;
     $RT::LocalHtmlPath ||= $RT::MasonComponentRoot;
+    $RT::LocalLibPath  ||= "$RT::LocalPath/lib";
 
-    my %path;
     my $with_subdirs = $ENV{WITH_SUBDIRS};
     @ARGV = grep { /WITH_SUBDIRS=(.*)/ ? ( ( $with_subdirs = $1 ), 0 ) : 1 }
         @ARGV;
@@ -69,36 +72,40 @@ sub RTx {
     my %subdirs;
     %subdirs = map { $_ => 1 } split( /\s*,\s*/, $with_subdirs )
         if defined $with_subdirs;
-
-    foreach (qw(bin etc html po sbin var)) {
-        next unless -d "$FindBin::Bin/$_";
-        next if keys %subdirs and !$subdirs{$_};
-        $self->no_index( directory => $_ );
-
-        no strict 'refs';
-        my $varname = "RT::Local" . ucfirst($_) . "Path";
-        $path{$_} = ${$varname} || "$RT::LocalPath/$_";
+    unless ( keys %subdirs ) {
+        $subdirs{$_} = 1 foreach grep -d "$FindBin::Bin/$_", @DIRS;
     }
 
-    $path{$_} .= "/$name" for grep $path{$_}, qw(etc po var);
-    $path{lib} = "$RT::LocalPath/lib" unless keys %subdirs and !$subdirs{'lib'};
-
     # If we're running on RT 3.8 with plugin support, we really wany
     # to install libs, mason templates and po files into plugin specific
     # directories
-    if ($RT::LocalPluginPath) {
-        foreach my $path (qw(lib po html etc bin sbin)) {
-            next unless -d "$FindBin::Bin/$path";
-            next if %subdirs and !$subdirs{$path};
-            $path{$path} = $RT::LocalPluginPath . "/$original_name/$path";
+    my %path;
+    if ( $RT::LocalPluginPath ) {
+        die "Because of bugs in RT 3.8.0 this extension can not be installed.\n"
+            ."Upgrade to RT 3.8.1 or newer.\n" if $RT::VERSION =~ /^3\.8\.0/;
+        $path{$_} = $RT::LocalPluginPath . "/$original_name/$_"
+            foreach @DIRS;
+    } else {
+        foreach ( @DIRS ) {
+            no strict 'refs';
+            my $varname = "RT::Local" . ucfirst($_) . "Path";
+            $path{$_} = ${$varname} || "$RT::LocalPath/$_";
         }
+
+        $path{$_} .= "/$name" for grep $path{$_}, qw(etc po var);
     }
 
-    my $args = join( ', ', map "q($_)", %path );
-    print "./$_\t=> $path{$_}\n" for sort keys %path;
+    my %index = map { $_ => 1 } @INDEX_DIRS;
+    $self->no_index( directory => $_ ) foreach grep !$index{$_}, @DIRS;
+
+    my $args = join ', ', map "q($_)", map { ($_, $path{$_}) }
+        grep $subdirs{$_}, keys %path;
 
-    if ( my @dirs = map { ( -D => $_ ) } grep $path{$_}, qw(bin html sbin) ) {
-        my @po = map { ( -o => $_ ) } grep -f,
+    print "./$_\t=> $path{$_}\n" for sort keys %subdirs;
+
+    if ( my @dirs = map { ( -D => $_ ) } grep $subdirs{$_}, qw(bin html sbin) ) {
+        my @po = map { ( -o => $_ ) }
+            grep -f,
             File::Glob::bsd_glob("po/*.po");
         $self->postamble(<< ".") if @po;
 lexicons ::
@@ -111,7 +118,7 @@ install ::
 \t\$(NOECHO) \$(PERL) -MExtUtils::Install -e \"install({$args})\"
 .
 
-    if ( $path{var} and -d $RT::MasonDataDir ) {
+    if ( $subdirs{var} and -d $RT::MasonDataDir ) {
         my ( $uid, $gid ) = ( stat($RT::MasonDataDir) )[ 4, 5 ];
         $postamble .= << ".";
 \t\$(NOECHO) chown -R $uid:$gid $path{var}
@@ -139,16 +146,17 @@ dropdb ::
     if ( -e 'etc/initialdata' ) { $has_etc{initialdata}++; }
 
     $self->postamble("$postamble\n");
-    if ( %subdirs and !$subdirs{'lib'} ) {
+    unless ( $subdirs{'lib'} ) {
         $self->makemaker_args( PM => { "" => "" }, );
     } else {
-        $self->makemaker_args( INSTALLSITELIB => "$RT::LocalPath/lib" );
+        $self->makemaker_args( INSTALLSITELIB => $path{'lib'} );
+        $self->makemaker_args( INSTALLARCHLIB => $path{'lib'} );
     }
 
-        $self->makemaker_args( INSTALLSITEMAN1DIR => "$RT::LocalPath/man/man1" );
-        $self->makemaker_args( INSTALLSITEMAN3DIR => "$RT::LocalPath/man/man3" );
-        $self->makemaker_args( INSTALLSITEARCH => "$RT::LocalPath/man" );
-        $self->makemaker_args( INSTALLARCHLIB => "$RT::LocalPath/lib" );
+    $self->makemaker_args( INSTALLSITEMAN1DIR => "$RT::LocalPath/man/man1" );
+    $self->makemaker_args( INSTALLSITEMAN3DIR => "$RT::LocalPath/man/man3" );
+    $self->makemaker_args( INSTALLSITEARCH => "$RT::LocalPath/man" );
+
     if (%has_etc) {
         $self->load('RTxInitDB');
         print "For first-time installation, type 'make initdb'.\n";
@@ -180,4 +188,4 @@ sub RTxInit {
 
 __END__
 
-#line 281
+#line 302
diff --git a/inc/Module/Install/Win32.pm b/inc/Module/Install/Win32.pm
index f8744e7..cff76a2 100644
--- a/inc/Module/Install/Win32.pm
+++ b/inc/Module/Install/Win32.pm
@@ -6,7 +6,7 @@ use Module::Install::Base;
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '0.72';
+	$VERSION = '0.77';
 	@ISA     = qw{Module::Install::Base};
 	$ISCORE  = 1;
 }
diff --git a/inc/Module/Install/WriteAll.pm b/inc/Module/Install/WriteAll.pm
index d1d8a06..f35620f 100644
--- a/inc/Module/Install/WriteAll.pm
+++ b/inc/Module/Install/WriteAll.pm
@@ -6,7 +6,7 @@ use Module::Install::Base;
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '0.72';
+	$VERSION = '0.77';
 	@ISA     = qw{Module::Install::Base};
 	$ISCORE  = 1;
 }
diff --git a/lib/RTFM/Extension/ArticleTemplates.pm b/lib/RTFM/Extension/ArticleTemplates.pm
index a9518a9..d522227 100644
--- a/lib/RTFM/Extension/ArticleTemplates.pm
+++ b/lib/RTFM/Extension/ArticleTemplates.pm
@@ -1,6 +1,6 @@
 package RTFM::Extension::ArticleTemplates;
 
-our $VERSION = '0.01';
+our $VERSION = '0.02';
 
 use 5.8.3;
 use strict;
@@ -37,6 +37,8 @@ commands:
     make
     make install
 
+Set @Plugins option if you're using RT 3.8.1 or newer.
+
 =head1 AUTHOR
 
 Kevin Falcone E<lt>falcone at bestpractical.comE<gt>

commit 465eb1d93dff7f78fb1d6fa2e088f96648565421
Author: Kevin Falcone <falcone at bestpractical.com>
Date:   Thu Jan 15 16:58:39 2009 +0000

    upgrade Module::Install::RTx

diff --git a/inc/Module/Install.pm b/inc/Module/Install.pm
index eb449ca..e6758c9 100644
--- a/inc/Module/Install.pm
+++ b/inc/Module/Install.pm
@@ -30,11 +30,7 @@ BEGIN {
 	# This is not enforced yet, but will be some time in the next few
 	# releases once we can make sure it won't clash with custom
 	# Module::Install extensions.
-	$VERSION = '0.77';
-
-	*inc::Module::Install::VERSION = *VERSION;
-	@inc::Module::Install::ISA     = __PACKAGE__;
-
+	$VERSION = '0.70';
 }
 
 
@@ -85,7 +81,7 @@ END_DIE
 
 # Build.PL was formerly supported, but no longer is due to excessive
 # difficulty in implementing every single feature twice.
-if ( $0 =~ /Build.PL$/i ) { die <<"END_DIE" }
+if ( $0 =~ /Build.PL$/i or -f 'Build.PL' ) { die <<"END_DIE" }
 
 Module::Install no longer supports Build.PL.
 
@@ -99,20 +95,14 @@ END_DIE
 
 
 
-# To save some more typing in Module::Install installers, every...
-# use inc::Module::Install
-# ...also acts as an implicit use strict.
-$^H |= strict::bits(qw(refs subs vars));
-
-
-
-
-
 use Cwd        ();
 use File::Find ();
 use File::Path ();
 use FindBin;
 
+*inc::Module::Install::VERSION = *VERSION;
+ at inc::Module::Install::ISA     = __PACKAGE__;
+
 sub autoload {
 	my $self = shift;
 	my $who  = $self->_caller;
@@ -125,10 +115,8 @@ sub autoload {
 			goto &$code unless $cwd eq $pwd;
 		}
 		$$sym =~ /([^:]+)$/ or die "Cannot autoload $who - $sym";
-		unless ( uc($1) eq $1 ) {
-			unshift @_, ( $self, $1 );
-			goto &{$self->can('call')};
-		}
+		unshift @_, ( $self, $1 );
+		goto &{$self->can('call')} unless uc($1) eq $1;
 	};
 }
 
@@ -157,7 +145,8 @@ sub import {
 }
 
 sub preload {
-	my $self = shift;
+	my ($self) = @_;
+
 	unless ( $self->{extensions} ) {
 		$self->load_extensions(
 			"$self->{prefix}/$self->{path}", $self
@@ -213,7 +202,6 @@ sub new {
 		$args{path}  =~ s!::!/!g;
 	}
 	$args{file}     ||= "$args{base}/$args{prefix}/$args{path}.pm";
-	$args{wrote}      = 0;
 
 	bless( \%args, $class );
 }
@@ -289,9 +277,9 @@ sub find_extensions {
 		# correctly.  Otherwise, root through the file to locate the case-preserved
 		# version of the package name.
 		if ( $subpath eq lc($subpath) || $subpath eq uc($subpath) ) {
-			my $content = Module::Install::_read($subpath . '.pm');
-			my $in_pod  = 0;
-			foreach ( split //, $content ) {
+			open PKGFILE, "<$subpath.pm" or die "find_extensions: Can't open $subpath.pm: $!";
+			my $in_pod = 0;
+			while ( <PKGFILE> ) {
 				$in_pod = 1 if /^=\w/;
 				$in_pod = 0 if /^=cut/;
 				next if ($in_pod || /^=cut/);  # skip pod text
@@ -301,6 +289,7 @@ sub find_extensions {
 					last;
 				}
 			}
+			close PKGFILE;
 		}
 
 		push @found, [ $file, $pkg ];
@@ -309,13 +298,6 @@ sub find_extensions {
 	@found;
 }
 
-
-
-
-
-#####################################################################
-# Utility Functions
-
 sub _caller {
 	my $depth = 0;
 	my $call  = caller($depth);
@@ -326,44 +308,6 @@ sub _caller {
 	return $call;
 }
 
-sub _read {
-	local *FH;
-	open FH, "< $_[0]" or die "open($_[0]): $!";
-	my $str = do { local $/; <FH> };
-	close FH or die "close($_[0]): $!";
-	return $str;
-}
-
-sub _write {
-	local *FH;
-	open FH, "> $_[0]" or die "open($_[0]): $!";
-	foreach ( 1 .. $#_ ) { print FH $_[$_] or die "print($_[0]): $!" }
-	close FH or die "close($_[0]): $!";
-}
-
-# _version is for processing module versions (eg, 1.03_05) not
-# Perl versions (eg, 5.8.1).
-
-sub _version ($) {
-	my $s = shift || 0;
-	   $s =~ s/^(\d+)\.?//;
-	my $l = $1 || 0;
-	my @v = map { $_ . '0' x (3 - length $_) } $s =~ /(\d{1,3})\D?/g;
-	   $l = $l . '.' . join '', @v if @v;
-	return $l + 0;
-}
-
-# Cloned from Params::Util::_CLASS
-sub _CLASS ($) {
-	(
-		defined $_[0]
-		and
-		! ref $_[0]
-		and
-		$_[0] =~ m/^[^\W\d]\w*(?:::\w+)*$/s
-	) ? $_[0] : undef;
-}
-
 1;
 
 # Copyright 2008 Adam Kennedy.
diff --git a/inc/Module/Install/AutoInstall.pm b/inc/Module/Install/AutoInstall.pm
index 8b3bcaa..3a490fb 100644
--- a/inc/Module/Install/AutoInstall.pm
+++ b/inc/Module/Install/AutoInstall.pm
@@ -6,7 +6,7 @@ use Module::Install::Base;
 
 use vars qw{$VERSION $ISCORE @ISA};
 BEGIN {
-	$VERSION = '0.77';
+	$VERSION = '0.68';
 	$ISCORE  = 1;
 	@ISA     = qw{Module::Install::Base};
 }
diff --git a/inc/Module/Install/Base.pm b/inc/Module/Install/Base.pm
index 433ebed..5e24ae1 100644
--- a/inc/Module/Install/Base.pm
+++ b/inc/Module/Install/Base.pm
@@ -1,7 +1,7 @@
 #line 1
 package Module::Install::Base;
 
-$VERSION = '0.77';
+$VERSION = '0.70';
 
 # Suspend handler for "redefined" warnings
 BEGIN {
@@ -45,8 +45,6 @@ sub admin {
     $_[0]->_top->{admin} or Module::Install::Base::FakeAdmin->new;
 }
 
-#line 101
-
 sub is_admin {
     $_[0]->admin->VERSION;
 }
@@ -69,4 +67,4 @@ BEGIN {
 
 1;
 
-#line 146
+#line 138
diff --git a/inc/Module/Install/Can.pm b/inc/Module/Install/Can.pm
index 9025607..9ce21a4 100644
--- a/inc/Module/Install/Can.pm
+++ b/inc/Module/Install/Can.pm
@@ -11,7 +11,7 @@ use ExtUtils::MakeMaker ();
 
 use vars qw{$VERSION $ISCORE @ISA};
 BEGIN {
-	$VERSION = '0.77';
+	$VERSION = '0.70';
 	$ISCORE  = 1;
 	@ISA     = qw{Module::Install::Base};
 }
@@ -39,7 +39,6 @@ sub can_run {
 	return $_cmd if (-x $_cmd or $_cmd = MM->maybe_command($_cmd));
 
 	for my $dir ((split /$Config::Config{path_sep}/, $ENV{PATH}), '.') {
-		next if $dir eq '';
 		my $abs = File::Spec->catfile($dir, $_[1]);
 		return $abs if (-x $abs or $abs = MM->maybe_command($abs));
 	}
@@ -80,4 +79,4 @@ if ( $^O eq 'cygwin' ) {
 
 __END__
 
-#line 158
+#line 157
diff --git a/inc/Module/Install/Fetch.pm b/inc/Module/Install/Fetch.pm
index d66aba5..2b8f6e8 100644
--- a/inc/Module/Install/Fetch.pm
+++ b/inc/Module/Install/Fetch.pm
@@ -6,7 +6,7 @@ use Module::Install::Base;
 
 use vars qw{$VERSION $ISCORE @ISA};
 BEGIN {
-	$VERSION = '0.77';
+	$VERSION = '0.70';
 	$ISCORE  = 1;
 	@ISA     = qw{Module::Install::Base};
 }
diff --git a/inc/Module/Install/Include.pm b/inc/Module/Install/Include.pm
index 0c7dc5a..14f2c7a 100644
--- a/inc/Module/Install/Include.pm
+++ b/inc/Module/Install/Include.pm
@@ -6,7 +6,7 @@ use Module::Install::Base;
 
 use vars qw{$VERSION $ISCORE @ISA};
 BEGIN {
-	$VERSION = '0.77';
+	$VERSION = '0.70';
 	$ISCORE  = 1;
 	@ISA     = qw{Module::Install::Base};
 }
diff --git a/inc/Module/Install/Makefile.pm b/inc/Module/Install/Makefile.pm
index 92cd1ef..27bbace 100644
--- a/inc/Module/Install/Makefile.pm
+++ b/inc/Module/Install/Makefile.pm
@@ -7,7 +7,7 @@ use ExtUtils::MakeMaker ();
 
 use vars qw{$VERSION $ISCORE @ISA};
 BEGIN {
-	$VERSION = '0.77';
+	$VERSION = '0.70';
 	$ISCORE  = 1;
 	@ISA     = qw{Module::Install::Base};
 }
@@ -36,9 +36,9 @@ sub prompt {
 
 sub makemaker_args {
 	my $self = shift;
-	my $args = ( $self->{makemaker_args} ||= {} );
-	%$args = ( %$args, @_ );
-	return $args;
+	my $args = ($self->{makemaker_args} ||= {});
+	  %$args = ( %$args, @_ ) if @_;
+	$args;
 }
 
 # For mm args that take multiple space-seperated args,
@@ -63,18 +63,18 @@ sub build_subdirs {
 sub clean_files {
 	my $self  = shift;
 	my $clean = $self->makemaker_args->{clean} ||= {};
-	  %$clean = (
+	%$clean = (
 		%$clean, 
-		FILES => join ' ', grep { length $_ } ($clean->{FILES} || (), @_),
+		FILES => join(' ', grep length, $clean->{FILES}, @_),
 	);
 }
 
 sub realclean_files {
-	my $self      = shift;
+	my $self  = shift;
 	my $realclean = $self->makemaker_args->{realclean} ||= {};
-	  %$realclean = (
+	%$realclean = (
 		%$realclean, 
-		FILES => join ' ', grep { length $_ } ($realclean->{FILES} || (), @_),
+		FILES => join(' ', grep length, $realclean->{FILES}, @_),
 	);
 }
 
@@ -116,19 +116,13 @@ sub write {
 
 	# Make sure we have a new enough
 	require ExtUtils::MakeMaker;
-
-	# MakeMaker can complain about module versions that include
-	# an underscore, even though its own version may contain one!
-	# Hence the funny regexp to get rid of it.  See RT #35800
-	# for details.
-
-	$self->configure_requires( 'ExtUtils::MakeMaker' => $ExtUtils::MakeMaker::VERSION =~ /^(\d+\.\d+)/ );
+	$self->configure_requires( 'ExtUtils::MakeMaker' => $ExtUtils::MakeMaker::VERSION );
 
 	# Generate the 
 	my $args = $self->makemaker_args;
 	$args->{DISTNAME} = $self->name;
-	$args->{NAME}     = $self->module_name || $self->name;
-	$args->{VERSION}  = $self->version;
+	$args->{NAME}     = $self->module_name || $self->name || $self->determine_NAME($args);
+	$args->{VERSION}  = $self->version || $self->determine_VERSION($args);
 	$args->{NAME}     =~ s/-/::/g;
 	if ( $self->tests ) {
 		$args->{test} = { TESTS => $self->tests };
@@ -181,9 +175,7 @@ sub write {
 
 	my $user_preop = delete $args{dist}->{PREOP};
 	if (my $preop = $self->admin->preop($user_preop)) {
-		foreach my $key ( keys %$preop ) {
-			$args{dist}->{$key} = $preop->{$key};
-		}
+		$args{dist} = $preop;
 	}
 
 	my $mm = ExtUtils::MakeMaker::WriteMakefile(%args);
@@ -250,4 +242,4 @@ sub postamble {
 
 __END__
 
-#line 379
+#line 371
diff --git a/inc/Module/Install/Metadata.pm b/inc/Module/Install/Metadata.pm
index 397fb97..a39ffde 100644
--- a/inc/Module/Install/Metadata.pm
+++ b/inc/Module/Install/Metadata.pm
@@ -6,43 +6,25 @@ use Module::Install::Base;
 
 use vars qw{$VERSION $ISCORE @ISA};
 BEGIN {
-	$VERSION = '0.77';
+	$VERSION = '0.70';
 	$ISCORE  = 1;
 	@ISA     = qw{Module::Install::Base};
 }
 
 my @scalar_keys = qw{
-	name
-	module_name
-	abstract
-	author
-	version
-	distribution_type
-	tests
-	installdirs
+	name module_name abstract author version license
+	distribution_type perl_version tests installdirs
 };
 
 my @tuple_keys = qw{
-	configure_requires
-	build_requires
-	requires
-	recommends
-	bundles
-	resources
+	configure_requires build_requires requires recommends bundles
 };
 
-my @resource_keys = qw{
-	homepage
-	bugtracker
-	repository
-};
-
-sub Meta              { shift          }
-sub Meta_ScalarKeys   { @scalar_keys   }
-sub Meta_TupleKeys    { @tuple_keys    }
-sub Meta_ResourceKeys { @resource_keys }
+sub Meta            { shift        }
+sub Meta_ScalarKeys { @scalar_keys }
+sub Meta_TupleKeys  { @tuple_keys  }
 
-foreach my $key ( @scalar_keys ) {
+foreach my $key (@scalar_keys) {
 	*$key = sub {
 		my $self = shift;
 		return $self->{values}{$key} if defined wantarray and !@_;
@@ -51,100 +33,33 @@ foreach my $key ( @scalar_keys ) {
 	};
 }
 
-foreach my $key ( @resource_keys ) {
+foreach my $key (@tuple_keys) {
 	*$key = sub {
 		my $self = shift;
-		unless ( @_ ) {
-			return () unless $self->{values}{resources};
-			return map  { $_->[1] }
-			       grep { $_->[0] eq $key }
-			       @{ $self->{values}{resources} };
+		return $self->{values}{$key} unless @_;
+
+		my @rv;
+		while (@_) {
+			my $module = shift or last;
+			my $version = shift || 0;
+			if ( $module eq 'perl' ) {
+				$version =~ s{^(\d+)\.(\d+)\.(\d+)}
+				             {$1 + $2/1_000 + $3/1_000_000}e;
+				$self->perl_version($version);
+				next;
+			}
+			my $rv = [ $module, $version ];
+			push @rv, $rv;
 		}
-		return $self->{values}{resources}{$key} unless @_;
-		my $uri = shift or die(
-			"Did not provide a value to $key()"
-		);
-		$self->resources( $key => $uri );
-		return 1;
+		push @{ $self->{values}{$key} }, @rv;
+		@rv;
 	};
 }
 
-sub requires {
-	my $self = shift;
-	while ( @_ ) {
-		my $module  = shift or last;
-		my $version = shift || 0;
-		push @{ $self->{values}{requires} }, [ $module, $version ];
-	}
-	$self->{values}{requires};
-}
-
-sub build_requires {
-	my $self = shift;
-	while ( @_ ) {
-		my $module  = shift or last;
-		my $version = shift || 0;
-		push @{ $self->{values}{build_requires} }, [ $module, $version ];
-	}
-	$self->{values}{build_requires};
-}
-
-sub configure_requires {
-	my $self = shift;
-	while ( @_ ) {
-		my $module  = shift or last;
-		my $version = shift || 0;
-		push @{ $self->{values}{configure_requires} }, [ $module, $version ];
-	}
-	$self->{values}{configure_requires};
-}
-
-sub recommends {
-	my $self = shift;
-	while ( @_ ) {
-		my $module  = shift or last;
-		my $version = shift || 0;
-		push @{ $self->{values}{recommends} }, [ $module, $version ];
-	}
-	$self->{values}{recommends};
-}
-
-sub bundles {
-	my $self = shift;
-	while ( @_ ) {
-		my $module  = shift or last;
-		my $version = shift || 0;
-		push @{ $self->{values}{bundles} }, [ $module, $version ];
-	}
-	$self->{values}{bundles};
-}
-
-# Resource handling
-my %lc_resource = map { $_ => 1 } qw{
-	homepage
-	license
-	bugtracker
-	repository
-};
-
-sub resources {
-	my $self = shift;
-	while ( @_ ) {
-		my $name  = shift or last;
-		my $value = shift or next;
-		if ( $name eq lc $name and ! $lc_resource{$name} ) {
-			die("Unsupported reserved lowercase resource '$name'");
-		}
-		$self->{values}{resources} ||= [];
-		push @{ $self->{values}{resources} }, [ $name, $value ];
-	}
-	$self->{values}{resources};
-}
-
 # Aliases for build_requires that will have alternative
 # meanings in some future version of META.yml.
-sub test_requires      { shift->build_requires(@_) }
-sub install_requires   { shift->build_requires(@_) }
+sub test_requires      { shift->build_requires(@_)  }
+sub install_requires   { shift->build_requires(@_)  }
 
 # Aliases for installdirs options
 sub install_as_core    { $_[0]->installdirs('perl')   }
@@ -154,90 +69,45 @@ sub install_as_vendor  { $_[0]->installdirs('vendor') }
 
 sub sign {
 	my $self = shift;
-	return $self->{values}{sign} if defined wantarray and ! @_;
-	$self->{values}{sign} = ( @_ ? $_[0] : 1 );
+	return $self->{'values'}{'sign'} if defined wantarray and ! @_;
+	$self->{'values'}{'sign'} = ( @_ ? $_[0] : 1 );
 	return $self;
 }
 
 sub dynamic_config {
 	my $self = shift;
 	unless ( @_ ) {
-		warn "You MUST provide an explicit true/false value to dynamic_config\n";
+		warn "You MUST provide an explicit true/false value to dynamic_config, skipping\n";
 		return $self;
 	}
-	$self->{values}{dynamic_config} = $_[0] ? 1 : 0;
-	return 1;
-}
-
-sub perl_version {
-	my $self = shift;
-	return $self->{values}{perl_version} unless @_;
-	my $version = shift or die(
-		"Did not provide a value to perl_version()"
-	);
-
-	# Convert triple-part versions (eg, 5.6.1 or 5.8.9) to
-	# numbers (eg, 5.006001 or 5.008009).
-
-	$version =~ s/^(\d+)\.(\d+)\.(\d+)$/sprintf("%d.%03d%03d",$1,$2,$3)/e;
-
-	$version =~ s/_.+$//;
-	$version = $version + 0; # Numify
-	unless ( $version >= 5.005 ) {
-		die "Module::Install only supports 5.005 or newer (use ExtUtils::MakeMaker)\n";
-	}
-	$self->{values}{perl_version} = $version;
-	return 1;
-}
-
-sub license {
-	my $self = shift;
-	return $self->{values}{license} unless @_;
-	my $license = shift or die(
-		'Did not provide a value to license()'
-	);
-	$self->{values}{license} = $license;
-
-	# Automatically fill in license URLs
-	if ( $license eq 'perl' ) {
-		$self->resources( license => 'http://dev.perl.org/licenses/' );
-	}
-
-	return 1;
+	$self->{'values'}{'dynamic_config'} = $_[0] ? 1 : 0;
+	return $self;
 }
 
 sub all_from {
 	my ( $self, $file ) = @_;
 
 	unless ( defined($file) ) {
-		my $name = $self->name or die(
-			"all_from called with no args without setting name() first"
-		);
+		my $name = $self->name
+			or die "all_from called with no args without setting name() first";
 		$file = join('/', 'lib', split(/-/, $name)) . '.pm';
 		$file =~ s{.*/}{} unless -e $file;
-		unless ( -e $file ) {
-			die("all_from cannot find $file from $name");
-		}
-	}
-	unless ( -f $file ) {
-		die("The path '$file' does not exist, or is not a file");
+		die "all_from: cannot find $file from $name" unless -e $file;
 	}
 
-	# Some methods pull from POD instead of code.
-	# If there is a matching .pod, use that instead
-	my $pod = $file;
-	$pod =~ s/\.pm$/.pod/i;
-	$pod = $file unless -e $pod;
-
-	# Pull the different values
-	$self->name_from($file)         unless $self->name;
 	$self->version_from($file)      unless $self->version;
 	$self->perl_version_from($file) unless $self->perl_version;
-	$self->author_from($pod)        unless $self->author;
-	$self->license_from($pod)       unless $self->license;
-	$self->abstract_from($pod)      unless $self->abstract;
 
-	return 1;
+	# The remaining probes read from POD sections; if the file
+	# has an accompanying .pod, use that instead
+	my $pod = $file;
+	if ( $pod =~ s/\.pm$/.pod/i and -e $pod ) {
+		$file = $pod;
+	}
+
+	$self->author_from($file)   unless $self->author;
+	$self->license_from($file)  unless $self->license;
+	$self->abstract_from($file) unless $self->abstract;
 }
 
 sub provides {
@@ -299,8 +169,8 @@ sub features {
 	while ( my ( $name, $mods ) = splice( @_, 0, 2 ) ) {
 		$self->feature( $name, @$mods );
 	}
-	return $self->{values}{features}
-		? @{ $self->{values}{features} }
+	return $self->{values}->{features}
+		? @{ $self->{values}->{features} }
 		: ();
 }
 
@@ -313,10 +183,10 @@ sub no_index {
 
 sub read {
 	my $self = shift;
-	$self->include_deps( 'YAML::Tiny', 0 );
+	$self->include_deps( 'YAML', 0 );
 
-	require YAML::Tiny;
-	my $data = YAML::Tiny::LoadFile('META.yml');
+	require YAML;
+	my $data = YAML::LoadFile('META.yml');
 
 	# Call methods explicitly in case user has already set some values.
 	while ( my ( $key, $value ) = each %$data ) {
@@ -356,51 +226,35 @@ sub abstract_from {
 	 );
 }
 
-# Add both distribution and module name
-sub name_from {
-	my ($self, $file) = @_;
-	if (
-		Module::Install::_read($file) =~ m/
-		^ \s*
-		package \s*
-		([\w:]+)
-		\s* ;
-		/ixms
-	) {
-		my ($name, $module_name) = ($1, $1);
-		$name =~ s{::}{-}g;
-		$self->name($name);
-		unless ( $self->module_name ) {
-			$self->module_name($module_name);
-		}
-	} else {
-		die("Cannot determine name from $file\n");
-	}
+sub _slurp {
+	local *FH;
+	open FH, "< $_[1]" or die "Cannot open $_[1].pod: $!";
+	do { local $/; <FH> };
 }
 
 sub perl_version_from {
-	my $self = shift;
+	my ( $self, $file ) = @_;
 	if (
-		Module::Install::_read($_[0]) =~ m/
+		$self->_slurp($file) =~ m/
 		^
-		(?:use|require) \s*
+		use \s*
 		v?
 		([\d_\.]+)
 		\s* ;
 		/ixms
 	) {
-		my $perl_version = $1;
-		$perl_version =~ s{_}{}g;
-		$self->perl_version($perl_version);
+		my $v = $1;
+		$v =~ s{_}{}g;
+		$self->perl_version($1);
 	} else {
-		warn "Cannot determine perl version info from $_[0]\n";
+		warn "Cannot determine perl version info from $file\n";
 		return;
 	}
 }
 
 sub author_from {
-	my $self    = shift;
-	my $content = Module::Install::_read($_[0]);
+	my ( $self, $file ) = @_;
+	my $content = $self->_slurp($file);
 	if ($content =~ m/
 		=head \d \s+ (?:authors?)\b \s*
 		([^\n]*)
@@ -414,14 +268,15 @@ sub author_from {
 		$author =~ s{E<gt>}{>}g;
 		$self->author($author);
 	} else {
-		warn "Cannot determine author info from $_[0]\n";
+		warn "Cannot determine author info from $file\n";
 	}
 }
 
 sub license_from {
-	my $self = shift;
+	my ( $self, $file ) = @_;
+
 	if (
-		Module::Install::_read($_[0]) =~ m/
+		$self->_slurp($file) =~ m/
 		(
 			=head \d \s+
 			(?:licen[cs]e|licensing|copyright|legal)\b
@@ -433,12 +288,8 @@ sub license_from {
 		my $license_text = $1;
 		my @phrases      = (
 			'under the same (?:terms|license) as perl itself' => 'perl',        1,
-			'GNU general public license'                      => 'gpl',         1,
 			'GNU public license'                              => 'gpl',         1,
-			'GNU lesser general public license'               => 'lgpl',        1,
 			'GNU lesser public license'                       => 'lgpl',        1,
-			'GNU library general public license'              => 'lgpl',        1,
-			'GNU library public license'                      => 'lgpl',        1,
 			'BSD license'                                     => 'bsd',         1,
 			'Artistic license'                                => 'artistic',    1,
 			'GPL'                                             => 'gpl',         1,
@@ -452,7 +303,7 @@ sub license_from {
 			$pattern =~ s{\s+}{\\s+}g;
 			if ( $license_text =~ /\b$pattern\b/i ) {
 				if ( $osi and $license_text =~ /All rights reserved/i ) {
-					print "WARNING: 'All rights reserved' in copyright may invalidate Open Source license.\n";
+					warn "LEGAL WARNING: 'All rights reserved' may invalidate Open Source licenses. Consider removing it.";
 				}
 				$self->license($license);
 				return 1;
@@ -460,41 +311,8 @@ sub license_from {
 		}
 	}
 
-	warn "Cannot determine license info from $_[0]\n";
+	warn "Cannot determine license info from $file\n";
 	return 'unknown';
 }
 
-sub bugtracker_from {
-	my $self    = shift;
-	my $content = Module::Install::_read($_[0]);
-	my @links   = $content =~ m/L\<(http\:\/\/rt\.cpan\.org\/[^>]+)\>/g;
-	unless ( @links ) {
-		warn "Cannot determine bugtracker info from $_[0]\n";
-		return 0;
-	}
-	if ( @links > 1 ) {
-		warn "Found more than on rt.cpan.org link in $_[0]\n";
-		return 0;
-	}
-
-	# Set the bugtracker
-	bugtracker( $links[0] );
-	return 1;
-}
-
-sub install_script {
-	my $self = shift;
-	my $args = $self->makemaker_args;
-	my $exe  = $args->{EXE_FILES} ||= [];
-        foreach ( @_ ) {
-		if ( -f $_ ) {
-			push @$exe, $_;
-		} elsif ( -d 'script' and -f "script/$_" ) {
-			push @$exe, "script/$_";
-		} else {
-			die("Cannot find script '$_'");
-		}
-	}
-}
-
 1;
diff --git a/inc/Module/Install/RTx.pm b/inc/Module/Install/RTx.pm
index 2028f5e..20a354b 100644
--- a/inc/Module/Install/RTx.pm
+++ b/inc/Module/Install/RTx.pm
@@ -8,7 +8,7 @@ no warnings 'once';
 
 use Module::Install::Base;
 use base 'Module::Install::Base';
-our $VERSION = '0.23';
+our $VERSION = '0.24';
 
 use FindBin;
 use File::Glob     ();
diff --git a/inc/Module/Install/Win32.pm b/inc/Module/Install/Win32.pm
index cff76a2..21a81ab 100644
--- a/inc/Module/Install/Win32.pm
+++ b/inc/Module/Install/Win32.pm
@@ -6,7 +6,7 @@ use Module::Install::Base;
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '0.77';
+	$VERSION = '0.70';
 	@ISA     = qw{Module::Install::Base};
 	$ISCORE  = 1;
 }
diff --git a/inc/Module/Install/WriteAll.pm b/inc/Module/Install/WriteAll.pm
index f35620f..a05592d 100644
--- a/inc/Module/Install/WriteAll.pm
+++ b/inc/Module/Install/WriteAll.pm
@@ -6,7 +6,7 @@ use Module::Install::Base;
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '0.77';
+	$VERSION = '0.70';
 	@ISA     = qw{Module::Install::Base};
 	$ISCORE  = 1;
 }

commit 7b54eeb4b012079e8169f2a3c9d75002b5e15435
Author: Kevin Falcone <falcone at bestpractical.com>
Date:   Thu Jan 15 16:59:12 2009 +0000

    cleanup

diff --git a/.cvsignore b/.cvsignore
deleted file mode 100644
index 6c579e6..0000000
--- a/.cvsignore
+++ /dev/null
@@ -1,10 +0,0 @@
-blib*
-Makefile
-Makefile.old
-Build
-_build*
-pm_to_blib*
-*.tar.gz
-.lwpcookies
-RTFM-Extension-ArticleTemplates-*
-cover_db

-----------------------------------------------------------------------



More information about the Bps-public-commit mailing list