#!/usr/bin/env perl
# THIS FILE IS AUTOGENERATED!

# if regular Mouse is loaded, bail out
unless ($INC{'Mouse.pm'}) {
eval q{

# tell Perl we already have all of the Mouse files loaded:
$INC{'Mouse.pm'} = __FILE__;
$INC{'Mouse/Object.pm'} = __FILE__;
$INC{'Mouse/Role.pm'} = __FILE__;
$INC{'Mouse/TypeRegistry.pm'} = __FILE__;
$INC{'Mouse/Util.pm'} = __FILE__;
$INC{'Mouse/Meta/Attribute.pm'} = __FILE__;
$INC{'Mouse/Meta/Class.pm'} = __FILE__;
$INC{'Mouse/Meta/Role.pm'} = __FILE__;

# and now their contents

package Mouse::Util;
use strict;
use warnings;
use base 'Exporter';
use Carp;

BEGIN {
    our %dependencies = (
        'Scalar::Util' => {

#       VVVVV   CODE TAKEN FROM SCALAR::UTIL   VVVVV
            'blessed' => do {
                *UNIVERSAL::a_sub_not_likely_to_be_here = sub {
                    my $ref = ref($_[0]);

                    # deviation from Scalar::Util
                    # XS returns undef, PP returns GLOB.
                    # let's make that more consistent by having PP return
                    # undef if it's a GLOB. :/

                    # \*STDOUT would be allowed as an object in PP blessed
                    # but not XS
                    return $ref eq 'GLOB' ? undef : $ref;
                };

                sub {
                    local($@, $SIG{__DIE__}, $SIG{__WARN__});
                    length(ref($_[0]))
                        ? eval { $_[0]->a_sub_not_likely_to_be_here }
                        : undef;
                },
            },
            'looks_like_number' => sub {
                local $_ = shift;

                # checks from perlfaq4
                return 0 if !defined($_) or ref($_);
                return 1 if (/^[+-]?\d+$/); # is a +/- integer
                return 1 if (/^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/); # a C float
                return 1 if ($] >= 5.008 and /^(Inf(inity)?|NaN)$/i) or ($] >= 5.006001 and /^Inf$/i);

                0;
            },
            'reftype' => sub {
                local($@, $SIG{__DIE__}, $SIG{__WARN__});
                my $r = shift;
                my $t;

                length($t = ref($r)) or return undef;

                # This eval will fail if the reference is not blessed
                eval { $r->a_sub_not_likely_to_be_here; 1 }
                ? do {
                    $t = eval {
                        # we have a GLOB or an IO. Stringify a GLOB gives it's name
                        my $q = *$r;
                        $q =~ /^\*/ ? "GLOB" : "IO";
                    }
                    or do {
                        # OK, if we don't have a GLOB what parts of
                        # a glob will it populate.
                        # NOTE: A glob always has a SCALAR
                        local *glob = $r;
                        defined *glob{ARRAY} && "ARRAY"
                            or defined *glob{HASH} && "HASH"
                            or defined *glob{CODE} && "CODE"
                            or length(ref(${$r})) ? "REF" : "SCALAR";
                    }
                }
                : $t
            },
            'openhandle' => sub {
                my $fh = shift;
                my $rt = reftype($fh) || '';

                return defined(fileno($fh)) ? $fh : undef
                    if $rt eq 'IO';

                if (reftype(\$fh) eq 'GLOB') { # handle  openhandle(*DATA)
                    $fh = \(my $tmp=$fh);
                }
                elsif ($rt ne 'GLOB') {
                    return undef;
                }

                (tied(*$fh) or defined(fileno($fh)))
                    ? $fh : undef;
            },
            weaken => {
                loaded => \&Scalar::Util::weaken,
                not_loaded => sub { die "Scalar::Util required for weak reference support" },
            },
#       ^^^^^   CODE TAKEN FROM SCALAR::UTIL   ^^^^^
        },
        'MRO::Compat' => {
#       VVVVV   CODE TAKEN FROM MRO::COMPAT   VVVVV
            'get_linear_isa' => {
                loaded     => \&mro::get_linear_isa,
                not_loaded => do {
                    # this recurses so it isn't pretty
                    my $code;
                    $code = sub {
                        no strict 'refs';

                        my $classname = shift;

                        my @lin = ($classname);
                        my %stored;
                        foreach my $parent (@{"$classname\::ISA"}) {
                            my $plin = $code->($parent);
                            foreach (@$plin) {
                                next if exists $stored{$_};
                                push(@lin, $_);
                                $stored{$_} = 1;
                            }
                        }
                        return \@lin;
                    }
                },
            },
#       ^^^^^   CODE TAKEN FROM MRO::COMPAT   ^^^^^
        },
#       VVVVV   CODE TAKEN FROM TEST::EXCEPTION   VVVVV
        'Test::Exception' => do {

            my $Tester;

            my $is_exception = sub {
                my $exception = shift;
                return ref $exception || $exception ne '';
            };

            my $exception_as_string = sub {
                my ( $prefix, $exception ) = @_;
                return "$prefix normal exit" unless $is_exception->( $exception );
                my $class = ref $exception;
                $exception = "$class ($exception)"
                        if $class && "$exception" !~ m/^\Q$class/;
                chomp $exception;
                return "$prefix $exception";
            };
            my $try_as_caller = sub {
                my $coderef = shift;
                eval { $coderef->() };
                $@;
            };

            {
                'throws_ok' => sub (&$;$) {
                    my ( $coderef, $expecting, $description ) = @_;
                    Carp::croak "throws_ok: must pass exception class/object or regex"
                        unless defined $expecting;
                    $description = $exception_as_string->( "threw", $expecting )
                        unless defined $description;
                    my $exception = $try_as_caller->($coderef);

                    $Tester ||= Test::Builder->new;

                    my $regex = $Tester->maybe_regex( $expecting );
                    my $ok = $regex
                        ? ( $exception =~ m/$regex/ )
                        : eval {
                            $exception->isa( ref $expecting ? ref $expecting : $expecting )
                        };
                    $Tester->ok( $ok, $description );
                    unless ( $ok ) {
                        $Tester->diag( $exception_as_string->( "expecting:", $expecting ) );
                        $Tester->diag( $exception_as_string->( "found:", $exception ) );
                    };
                    $@ = $exception;
                    return $ok;
                },
                'lives_ok' => sub (&;$) {
                    my ( $coderef, $description ) = @_;
                    my $exception = $try_as_caller->( $coderef );

                    $Tester ||= Test::Builder->new;

                    my $ok = $Tester->ok( ! $is_exception->( $exception ), $description );
                    $Tester->diag( $exception_as_string->( "died:", $exception ) ) unless $ok;
                    $@ = $exception;
                    return $ok;
                },
            },
        },
    );

    our %loaded;

    our @EXPORT_OK = map { keys %$_ } values %dependencies;
    our %EXPORT_TAGS = (
        all  => \@EXPORT_OK,
        test => [qw/throws_ok lives_ok/],
    );

    for my $module_name (keys %dependencies) {
        my $loaded = do {
            local $SIG{__DIE__} = 'DEFAULT';
            eval "require $module_name; 1";
        };

        $loaded{$module_name} = $loaded;

        for my $method_name (keys %{ $dependencies{ $module_name } }) {
            my $producer = $dependencies{$module_name}{$method_name};
            my $implementation;

            if (ref($producer) eq 'HASH') {
                $implementation = $loaded
                                ? $producer->{loaded}
                                : $producer->{not_loaded};
            }
            else {
                $implementation = $loaded
                                ? $module_name->can($method_name)
                                : $producer;
            }

            no strict 'refs';
            *{ __PACKAGE__ . '::' . $method_name } = $implementation;
        }
    }
}

package Mouse;
use strict;
use warnings;
use base 'Exporter';

our $VERSION = '0.09';
use 5.006;

use Carp 'confess';
BEGIN { Mouse::Util->import('blessed') }

our @EXPORT = qw(extends has before after around blessed confess with);

sub extends { Mouse::Meta::Class->initialize(caller)->superclasses(@_) }

sub has {
    my $meta = Mouse::Meta::Class->initialize(caller);

    my $names = shift;
    $names = [$names] if !ref($names);

    for my $name (@$names) {
        if ($name =~ s/^\+//) {
            Mouse::Meta::Attribute->clone_parent($meta, $name, @_);
        }
        else {
            Mouse::Meta::Attribute->create($meta, $name, @_);
        }
    }
}

sub before {
    my $meta = Mouse::Meta::Class->initialize(caller);

    my $code = pop;

    for (@_) {
        $meta->add_before_method_modifier($_ => $code);
    }
}

sub after {
    my $meta = Mouse::Meta::Class->initialize(caller);

    my $code = pop;

    for (@_) {
        $meta->add_after_method_modifier($_ => $code);
    }
}

sub around {
    my $meta = Mouse::Meta::Class->initialize(caller);

    my $code = pop;

    for (@_) {
        $meta->add_around_method_modifier($_ => $code);
    }
}

sub with {
    my $meta = Mouse::Meta::Class->initialize(caller);

    my $role  = shift;

    confess "Mouse::Role only supports 'with' on individual roles at a time" if @_;

    Mouse::load_class($role);
    $role->meta->apply($meta);
}

sub import {
    strict->import;
    warnings->import;

    my $caller = caller;

    my $meta = Mouse::Meta::Class->initialize($caller);
    $meta->superclasses('Mouse::Object')
        unless $meta->superclasses;

    no strict 'refs';
    no warnings 'redefine';
    *{$caller.'::meta'} = sub { $meta };

    Mouse->export_to_level(1, @_);
}

sub unimport {
    my $caller = caller;

    no strict 'refs';
    for my $keyword (@EXPORT) {
        delete ${ $caller . '::' }{$keyword};
    }
}

sub load_class {
    my $class = shift;

    if (ref($class) || !defined($class) || !length($class)) {
        my $display = defined($class) ? $class : 'undef';
        confess "Invalid class name ($display)";
    }

    return 1 if is_class_loaded($class);

    (my $file = "$class.pm") =~ s{::}{/}g;

    eval { CORE::require($file) };
    confess "Could not load class ($class) because : $@" if $@;

    return 1;
}

sub is_class_loaded {
    my $class = shift;

    return 0 if ref($class) || !defined($class) || !length($class);

    # walk the symbol table tree to avoid autovififying
    # \*{${main::}{"Foo::"}} == \*main::Foo::

    my $pack = \*::;
    foreach my $part (split('::', $class)) {
        return 0 unless exists ${$$pack}{"${part}::"};
        $pack = \*{${$$pack}{"${part}::"}};
    }

    # check for $VERSION or @ISA
    return 1 if exists ${$$pack}{VERSION}
             && defined *{${$$pack}{VERSION}}{SCALAR};
    return 1 if exists ${$$pack}{ISA}
             && defined *{${$$pack}{ISA}}{ARRAY};

    # check for any method
    foreach ( keys %{$$pack} ) {
        next if substr($_, -2, 2) eq '::';
        return 1 if defined *{${$$pack}{$_}}{CODE};
    }

    # fail
    return 0;
}

package Mouse::Meta::Attribute;
use strict;
use warnings;

use Carp 'confess';
BEGIN { Mouse::Util->import(qw/blessed weaken/) }

sub new {
    my $class = shift;
    my %args  = @_;

    my $name = $args{name};

    $args{init_arg} = $name
        unless exists $args{init_arg};

    $args{is} ||= '';

    bless \%args, $class;
}

sub name              { $_[0]->{name}             }
sub associated_class  { $_[0]->{associated_class} }
sub _is_metadata      { $_[0]->{is}               }
sub is_required       { $_[0]->{required}         }
sub default           { $_[0]->{default}          }
sub is_lazy           { $_[0]->{lazy}             }
sub is_lazy_build     { $_[0]->{lazy_build}       }
sub predicate         { $_[0]->{predicate}        }
sub clearer           { $_[0]->{clearer}          }
sub handles           { $_[0]->{handles}          }
sub is_weak_ref       { $_[0]->{weak_ref}         }
sub init_arg          { $_[0]->{init_arg}         }
sub type_constraint   { $_[0]->{type_constraint}  }
sub trigger           { $_[0]->{trigger}          }
sub builder           { $_[0]->{builder}          }
sub should_auto_deref { $_[0]->{auto_deref}       }

sub has_default         { exists $_[0]->{default}         }
sub has_predicate       { exists $_[0]->{predicate}       }
sub has_clearer         { exists $_[0]->{clearer}         }
sub has_handles         { exists $_[0]->{handles}         }
sub has_type_constraint { exists $_[0]->{type_constraint} }
sub has_trigger         { exists $_[0]->{trigger}         }
sub has_builder         { exists $_[0]->{builder}         }

sub _create_args {
    $_[0]->{_create_args} = $_[1] if @_ > 1;
    $_[0]->{_create_args}
}

sub generate_accessor {
    my $attribute = shift;

    my $name       = $attribute->name;
    my $key        = $name;
    my $default    = $attribute->default;
    my $type       = $attribute->type_constraint;
    my $constraint = $attribute->find_type_constraint;
    my $builder    = $attribute->builder;
    my $trigger    = $attribute->trigger;

    my $accessor = 'sub {
        my $self = shift;';

    if ($attribute->_is_metadata eq 'rw') {
        $accessor .= 'if (@_) {
            local $_ = $_[0];';

        if ($constraint) {
            $accessor .= 'unless ($constraint->()) {
                    my $display = defined($_) ? overload::StrVal($_) : "undef";
                    Carp::confess("Attribute ($name) does not pass the type constraint because: Validation failed for \'$type\' failed with value $display");
            }'
        }

        $accessor .= '$self->{$key} = $_;';

        if ($attribute->is_weak_ref) {
            $accessor .= 'weaken($self->{$key}) if ref($self->{$key});';
        }

        if ($trigger) {
            $accessor .= '$trigger->($self, $_, $attribute);';
        }

        $accessor .= '}';
    }
    else {
        $accessor .= 'confess "Cannot assign a value to a read-only accessor" if @_;';
    }

    if ($attribute->is_lazy) {
        $accessor .= '$self->{$key} = ';

        $accessor .= $attribute->has_builder
                   ? '$self->$builder'
                     : ref($default) eq 'CODE'
                     ? '$default->($self)'
                     : '$default';

        $accessor .= ' if !exists($self->{$key});';
    }

    if ($attribute->should_auto_deref) {
        if ($attribute->type_constraint eq 'ArrayRef') {
            $accessor .= 'if (wantarray) {
                return @{ $self->{$key} || [] };
            }';
        }
        else {
            $accessor .= 'if (wantarray) {
                return %{ $self->{$key} || {} };
            }';
        }
    }

    $accessor .= 'return $self->{$key};
    }';

    return eval $accessor;
}

sub generate_predicate {
    my $attribute = shift;
    my $key = $attribute->name;

    my $predicate = 'sub { exists($_[0]->{$key}) }';

    return eval $predicate;
}

sub generate_clearer {
    my $attribute = shift;
    my $key = $attribute->name;

    my $predicate = 'sub { delete($_[0]->{$key}) }';

    return eval $predicate;
}

sub generate_handles {
    my $attribute = shift;
    my $reader = $attribute->name;
    my %handles = $attribute->_canonicalize_handles($attribute->handles);

    my %method_map;

    for my $local_method (keys %handles) {
        my $remote_method = $handles{$local_method};

        my $method = 'sub {
            my $self = shift;
            $self->$reader->$remote_method(@_)
        }';

        $method_map{$local_method} = eval $method;
    }

    return \%method_map;
}

sub create {
    my ($self, $class, $name, %args) = @_;

    $args{name} = $name;
    $args{associated_class} = $class;

    %args = $self->canonicalize_args($name, %args);
    $self->validate_args($name, \%args);

    $args{type_constraint} = delete $args{isa}
        if exists $args{isa};

    my $attribute = $self->new(%args);

    $attribute->_create_args(\%args);

    $class->add_attribute($attribute);

    # install an accessor
    if ($attribute->_is_metadata eq 'rw' || $attribute->_is_metadata eq 'ro') {
        my $accessor = $attribute->generate_accessor;
        $class->add_method($name => $accessor);
    }

    for my $method (qw/predicate clearer/) {
        my $predicate = "has_$method";
        if ($attribute->$predicate) {
            my $generator = "generate_$method";
            my $coderef = $attribute->$generator;
            $class->add_method($attribute->$method => $coderef);
        }
    }

    if ($attribute->has_handles) {
        my $method_map = $attribute->generate_handles;
        for my $method_name (keys %$method_map) {
            $class->add_method($method_name => $method_map->{$method_name});
        }
    }

    return $attribute;
}

sub canonicalize_args {
    my $self = shift;
    my $name = shift;
    my %args = @_;

    if ($args{lazy_build}) {
        $args{lazy}      = 1;
        $args{required}  = 1;
        $args{builder}   = "_build_${name}"
            if !exists($args{builder});
        if ($name =~ /^_/) {
            $args{clearer}   = "_clear${name}" if !exists($args{clearer});
            $args{predicate} = "_has${name}" if !exists($args{predicate});
        }
        else {
            $args{clearer}   = "clear_${name}" if !exists($args{clearer});
            $args{predicate} = "has_${name}" if !exists($args{predicate});
        }
    }

    return %args;
}

sub validate_args {
    my $self = shift;
    my $name = shift;
    my $args = shift;

    confess "You can not use lazy_build and default for the same attribute ($name)"
        if $args->{lazy_build} && exists $args->{default};

    confess "You cannot have lazy attribute ($name) without specifying a default value for it"
        if $args->{lazy}
        && !exists($args->{default})
        && !exists($args->{builder});

    confess "References are not allowed as default values, you must wrap the default of '$name' in a CODE reference (ex: sub { [] } and not [])"
        if ref($args->{default})
        && ref($args->{default}) ne 'CODE';

    confess "You cannot auto-dereference without specifying a type constraint on attribute ($name)"
        if $args->{auto_deref} && !exists($args->{isa});

    confess "You cannot auto-dereference anything other than a ArrayRef or HashRef on attribute ($name)"
        if $args->{auto_deref}
        && $args->{isa} ne 'ArrayRef'
        && $args->{isa} ne 'HashRef';

    if ($args->{trigger}) {
        if (ref($args->{trigger}) eq 'HASH') {
            Carp::carp "HASH-based form of trigger has been removed. Only the coderef form of triggers are now supported.";
        }

        confess "Trigger must be a CODE ref on attribute ($name)"
            if ref($args->{trigger}) ne 'CODE';
    }

    return 1;
}

sub find_type_constraint {
    my $self = shift;
    my $type = $self->type_constraint;

    return unless $type;

    my $checker = Mouse::TypeRegistry->optimized_constraints->{$type};
    return $checker if $checker;

    return sub { blessed($_) && blessed($_) eq $type };
}

sub verify_type_constraint {
    my $self = shift;
    local $_ = shift;

    my $type = $self->type_constraint
        or return 1;
    my $constraint = $self->find_type_constraint;

    return 1 if $constraint->($_);

    my $name = $self->name;
    my $display = defined($_) ? overload::StrVal($_) : 'undef';
    Carp::confess("Attribute ($name) does not pass the type constraint because: Validation failed for \'$type\' failed with value $display");
}

sub _canonicalize_handles {
    my $self    = shift;
    my $handles = shift;

    if (ref($handles) eq 'HASH') {
        return %$handles;
    }
    elsif (ref($handles) eq 'ARRAY') {
        return map { $_ => $_ } @$handles;
    }
    else {
        confess "Unable to canonicalize the 'handles' option with $handles";
    }
}

sub clone_parent {
    my $self  = shift;
    my $class = shift;
    my $name  = shift;
    my %args  = ($self->get_parent_args($class, $name), @_);

    $self->create($class, $name, %args);
}

sub get_parent_args {
    my $self  = shift;
    my $class = shift;
    my $name  = shift;

    for my $super ($class->linearized_isa) {
        my $super_attr = $super->can("meta") && $super->meta->get_attribute($name)
            or next;
        return %{ $super_attr->_create_args };
    }

    confess "Could not find an attribute by the name of '$name' to inherit from";
}

package Mouse::Meta::Class;
use strict;
use warnings;

BEGIN { Mouse::Util->import(qw/get_linear_isa blessed/) }
use Carp 'confess';

do {
    my %METACLASS_CACHE;

    # because Mouse doesn't introspect existing classes, we're forced to
    # only pay attention to other Mouse classes
    sub _metaclass_cache {
        my $class = shift;
        my $name  = shift;
        return $METACLASS_CACHE{$name};
    }

    sub initialize {
        my $class = shift;
        my $name  = shift;
        $METACLASS_CACHE{$name} = $class->new(name => $name)
            if !exists($METACLASS_CACHE{$name});
        return $METACLASS_CACHE{$name};
    }
};

sub new {
    my $class = shift;
    my %args  = @_;

    $args{attributes} = {};
    $args{superclasses} = do {
        no strict 'refs';
        \@{ $args{name} . '::ISA' };
    };

    bless \%args, $class;
}

sub name { $_[0]->{name} }

sub superclasses {
    my $self = shift;

    if (@_) {
        Mouse::load_class($_) for @_;
        @{ $self->{superclasses} } = @_;
    }

    @{ $self->{superclasses} };
}

sub add_method {
    my $self = shift;
    my $name = shift;
    my $code = shift;

    my $pkg = $self->name;

    no strict 'refs';
    *{ $pkg . '::' . $name } = $code;
}

sub add_attribute {
    my $self = shift;
    my $attr = shift;

    $self->{'attributes'}{$attr->name} = $attr;
}

sub compute_all_applicable_attributes {
    my $self = shift;
    my (@attr, %seen);

    for my $class ($self->linearized_isa) {
        my $meta = $self->_metaclass_cache($class)
            or next;

        for my $name (keys %{ $meta->get_attribute_map }) {
            next if $seen{$name}++;
            push @attr, $meta->get_attribute($name);
        }
    }

    return @attr;
}

sub get_attribute_map { $_[0]->{attributes} }
sub has_attribute     { exists $_[0]->{attributes}->{$_[1]} }
sub get_attribute     { $_[0]->{attributes}->{$_[1]} }

sub linearized_isa { @{ get_linear_isa($_[0]->name) } }

sub clone_object {
    my $class    = shift;
    my $instance = shift;

    (blessed($instance) && $instance->isa($class->name))
        || confess "You must pass an instance of the metaclass (" . $class->name . "), not ($instance)";

    $class->clone_instance($instance, @_);
}

sub clone_instance {
    my ($class, $instance, %params) = @_;

    (blessed($instance))
        || confess "You can only clone instances, ($instance) is not a blessed instance";

    my $clone = bless { %$instance }, ref $instance;

    foreach my $attr ($class->compute_all_applicable_attributes()) {
        if ( defined( my $init_arg = $attr->init_arg ) ) {
            if (exists $params{$init_arg}) {
                $clone->{ $attr->name } = $params{$init_arg};
            }
        }
    }

    return $clone;

}

sub make_immutable {}
sub is_immutable { 0 }

sub attribute_metaclass { "Mouse::Meta::Class" }

sub add_before_method_modifier {
    my ($self, $name, $code) = @_;
    require Class::Method::Modifiers;
    Class::Method::Modifiers::_install_modifier(
        $self->name,
        'before',
        $name,
        $code,
    );
}

sub add_around_method_modifier {
    my ($self, $name, $code) = @_;
    require Class::Method::Modifiers;
    Class::Method::Modifiers::_install_modifier(
        $self->name,
        'around',
        $name,
        $code,
    );
}

sub add_after_method_modifier {
    my ($self, $name, $code) = @_;
    require Class::Method::Modifiers;
    Class::Method::Modifiers::_install_modifier(
        $self->name,
        'after',
        $name,
        $code,
    );
}

package Mouse::Meta::Role;
use strict;
use warnings;

do {
    my %METACLASS_CACHE;

    # because Mouse doesn't introspect existing classes, we're forced to
    # only pay attention to other Mouse classes
    sub _metaclass_cache {
        my $class = shift;
        my $name  = shift;
        return $METACLASS_CACHE{$name};
    }

    sub initialize {
        my $class = shift;
        my $name  = shift;
        $METACLASS_CACHE{$name} = $class->new(name => $name)
            if !exists($METACLASS_CACHE{$name});
        return $METACLASS_CACHE{$name};
    }
};

sub new {
    my $class = shift;
    my %args  = @_;

    $args{attributes} ||= {};

    bless \%args, $class;
}

sub name { $_[0]->{name} }

sub add_attribute {
    my $self = shift;
    my $name = shift;
    my $spec = shift;
    $self->{attributes}->{$name} = $spec;
}

sub has_attribute { exists $_[0]->{attributes}->{$_[1]}  }
sub get_attribute_list { keys %{ $_[0]->{attributes} } }
sub get_attribute { $_[0]->{attributes}->{$_[1]} }

sub apply {
    my $self  = shift;
    my $class = shift;

    for my $name ($self->get_attribute_list) {
        next if $class->has_attribute($name);
        my $spec = $self->get_attribute($name);
        Mouse::Meta::Attribute->create($class, $name, %$spec);
    }

    for my $modifier_type (qw/before after around/) {
        my $add_method = "add_${modifier_type}_method_modifier";
        my $modified = $self->{"${modifier_type}_method_modifiers"};

        for my $method_name (keys %$modified) {
            for my $code (@{ $modified->{$method_name} }) {
                $class->$add_method($method_name => $code);
            }
        }
    }
}

for my $modifier_type (qw/before after around/) {
    no strict 'refs';
    *{ __PACKAGE__ . '::' . "add_${modifier_type}_method_modifier" } = sub {
        my ($self, $method_name, $method) = @_;

        push @{ $self->{"${modifier_type}_method_modifiers"}->{$method_name} },
            $method;
    };

    *{ __PACKAGE__ . '::' . "get_${modifier_type}_method_modifiers" } = sub {
        my ($self, $method_name, $method) = @_;
        @{ $self->{"${modifier_type}_method_modifiers"}->{$method_name} || [] }
    };
}

package Mouse::Object;
use strict;
use warnings;

BEGIN { Mouse::Util->import(qw/weaken/) }
use Carp 'confess';

sub new {
    my $class = shift;

    my $args = $class->BUILDARGS(@_);

    my $instance = bless {}, $class;

    for my $attribute ($class->meta->compute_all_applicable_attributes) {
        my $from = $attribute->init_arg;
        my $key  = $attribute->name;
        my $default;

        if (defined($from) && exists($args->{$from})) {
            $attribute->verify_type_constraint($args->{$from})
                if $attribute->has_type_constraint;

            $instance->{$key} = $args->{$from};

            weaken($instance->{$key})
                if ref($instance->{$key}) && $attribute->is_weak_ref;

            if ($attribute->has_trigger) {
                $attribute->trigger->($instance, $args->{$from}, $attribute);
            }
        }
        else {
            if ($attribute->has_default || $attribute->has_builder) {
                unless ($attribute->is_lazy) {
                    my $default = $attribute->default;
                    my $builder = $attribute->builder;
                    my $value = $attribute->has_builder
                              ? $instance->$builder
                              : ref($default) eq 'CODE'
                                  ? $default->()
                                  : $default;

                    $attribute->verify_type_constraint($value)
                        if $attribute->has_type_constraint;

                    $instance->{$key} = $value;

                    weaken($instance->{$key})
                        if ref($instance->{$key}) && $attribute->is_weak_ref;
                }
            }
            else {
                if ($attribute->is_required) {
                    confess "Attribute (".$attribute->name.") is required";
                }
            }
        }
    }

    $instance->BUILDALL($args);

    return $instance;
}

sub BUILDARGS {
    my $class = shift;

    if (scalar @_ == 1) {
        if (defined $_[0]) {
            (ref($_[0]) eq 'HASH')
                || confess "Single parameters to new() must be a HASH ref";
            return {%{$_[0]}};
        } else {
            return {};
        }
    }
    else {
        return {@_};
    }
}

sub DESTROY { shift->DEMOLISHALL }

sub BUILDALL {
    my $self = shift;

    # short circuit
    return unless $self->can('BUILD');

    for my $class (reverse $self->meta->linearized_isa) {
        no strict 'refs';
        no warnings 'once';
        my $code = *{ $class . '::BUILD' }{CODE}
            or next;
        $code->($self, @_);
    }
}

sub DEMOLISHALL {
    my $self = shift;

    # short circuit
    return unless $self->can('DEMOLISH');

    no strict 'refs';

    for my $class ($self->meta->linearized_isa) {
        my $code = *{ $class . '::DEMOLISH' }{CODE}
            or next;
        $code->($self, @_);
    }
}

package Mouse::Role;
use strict;
use warnings;
use base 'Exporter';

use Carp 'confess';
BEGIN { Mouse::Util->import('blessed') }

our @EXPORT = qw(before after around has extends with requires excludes confess blessed);

sub before {
    my $meta = Mouse::Meta::Role->initialize(caller);

    my $code = pop;
    for (@_) {
        $meta->add_before_method_modifier($_ => $code);
    }
}

sub after {
    my $meta = Mouse::Meta::Role->initialize(caller);

    my $code = pop;
    for (@_) {
        $meta->add_after_method_modifier($_ => $code);
    }
}

sub around {
    my $meta = Mouse::Meta::Role->initialize(caller);

    my $code = pop;
    for (@_) {
        $meta->add_around_method_modifier($_ => $code);
    }
}

sub has {
    my $meta = Mouse::Meta::Role->initialize(caller);

    my $name = shift;
    my %opts = @_;

    $meta->add_attribute($name => \%opts);
}

sub extends  { confess "Roles do not support 'extends'" }

sub with     { confess "Mouse::Role does not currently support 'with'" }

sub requires { confess "Mouse::Role does not currently support 'requires'" }

sub excludes { confess "Mouse::Role does not currently support 'excludes'" }

sub import {
    strict->import;
    warnings->import;

    my $caller = caller;
    my $meta = Mouse::Meta::Role->initialize(caller);

    no strict 'refs';
    no warnings 'redefine';
    *{$caller.'::meta'} = sub { $meta };

    Mouse::Role->export_to_level(1, @_);
}

sub unimport {
    my $caller = caller;

    no strict 'refs';
    for my $keyword (@EXPORT) {
        delete ${ $caller . '::' }{$keyword};
    }
}

package Mouse::TypeRegistry;
use strict;
use warnings;

BEGIN { Mouse::Util->import(qw/blessed looks_like_number openhandle/) }

no warnings 'uninitialized';
sub optimized_constraints {
    return {
        Any        => sub { 1 },
        Item       => sub { 1 },
        Bool       => sub {
            !defined($_) || $_ eq "" || "$_" eq '1' || "$_" eq '0'
        },
        Undef      => sub { !defined($_) },
        Defined    => sub { defined($_) },
        Value      => sub { defined($_) && !ref($_) },
        Num        => sub { !ref($_) && looks_like_number($_) },
        Int        => sub { defined($_) && !ref($_) && /^-?[0-9]+$/ },
        Str        => sub { defined($_) && !ref($_) },
        ClassName  => sub { Mouse::is_class_loaded($_) },
        Ref        => sub { ref($_) },

        ScalarRef  => sub { ref($_) eq 'SCALAR' },
        ArrayRef   => sub { ref($_) eq 'ARRAY'  },
        HashRef    => sub { ref($_) eq 'HASH'   },
        CodeRef    => sub { ref($_) eq 'CODE'   },
        RegexpRef  => sub { ref($_) eq 'Regexp' },
        GlobRef    => sub { ref($_) eq 'GLOB'   },

        FileHandle => sub {
                ref($_) eq 'GLOB'
                && openhandle($_)
            or
                blessed($_)
                && $_->isa("IO::Handle")
        },

        Object     => sub { blessed($_) && blessed($_) ne 'Regexp' },
    };
}

}; #eval
} #unless

package Mouse::Tiny;
use base 'Mouse';

1;

