The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
use Class::Std::Fast::Storable constructor => 'none';
use base qw(SOAP::WSDL::XSD::Typelib::ComplexType);

Class::Std::initialize();

{ # BLOCK to scope variables
[%
atomic_types = {};

FOREACH element = complexType.get_element;
    name = XSD.perl_var_name(XSD.element_name(element)); %]
my %[% XSD.perl_name(name) %]_of :ATTR(:get<[% XSD.perl_name(name) %]>);
[%- END %]

__PACKAGE__->_factory(
    [ qw([% FOREACH element = complexType.get_element;

    # ugly copied code - macro or plugin method?
    name = XSD.perl_var_name(XSD.element_name(element)); -%]
        [% name %]
[% END %]
    ) ],
    {
[% FOREACH element = complexType.get_element;
    # ugly copied code - macro or plugin method?
    name = XSD.perl_var_name(XSD.element_name(element)); -%]
        '[% name %]' => \%[% XSD.perl_name(name) %]_of,
[% END -%]
    },
    {
[% FOREACH element = complexType.get_element;
    IF (ref = element.get_ref);
        ref_element = definitions.first_types.find_element(element.expand( ref ));
        -%]
        '[% XSD.perl_var_name(XSD.element_name(ref_element)) %]' => '[% XSD.create_xsd_name(ref_element) %]',

[%    ELSIF (type = element.get_type);
        element_type = definitions.first_types.find_type(complexType.expand( type ));
        IF (! element_type);
            type_name = complexType.expand( type );
            THROW NOT_FOUND, "${ type_name.0 } ${ type_name.1 } not found";
        END;
-%]
        '[% XSD.perl_var_name(XSD.element_name(element)) %]' => '[% XSD.create_xsd_name(element_type) %]',
[%  ELSE;
        IF (element.first_simpleType);
            atomic_types.${ element.get_name } = element.first_simpleType;
        ELSIF (element.first_complexType);
            atomic_types.${ element.get_name } = element.first_complexType;
        ELSE;
            THROW NOT_IMPLEMENTED , "Neither simple nor complex atomic type for element ${ element.get_name } - don't know what to do with it";
        END; %]
        '[% XSD.perl_var_name(XSD.element_name(element)) %]' => '[% XSD.create_subpackage_name({ value => element }) %]',
[%  END;
END -%]
    },
    {
[% FOREACH element = complexType.get_element; %]
        '[% XSD.perl_var_name(XSD.element_name(element)); %]' => '[% element.get_name %]',
[%- END %]
    }
);

} # end BLOCK

[% INCLUDE complexType/atomicTypes.tt(atomic_types = atomic_types) %]