The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
Changes 042
MANIFEST 050
META.json 53
META.yml 43
Makefile.PL 11
README.md 042
TODO 08
bin/awhois.pl 0150
lib/Net/Whois/Generic.pm 0735
lib/Net/Whois/Object/AsBlock/AFRINIC.pm 0181
lib/Net/Whois/Object/AsBlock/APNIC.pm 0184
lib/Net/Whois/Object/AsSet/AFRINIC.pm 0206
lib/Net/Whois/Object/AsSet/APNIC.pm 0212
lib/Net/Whois/Object/AsSet.pm 11
lib/Net/Whois/Object/AutNum/AFRINIC.pm 0259
lib/Net/Whois/Object/AutNum/APNIC.pm 0263
lib/Net/Whois/Object/AutNum.pm 49
lib/Net/Whois/Object/Domain/AFRINIC.pm 0236
lib/Net/Whois/Object/Domain/APNIC.pm 0238
lib/Net/Whois/Object/FilterSet/AFRINIC.pm 0211
lib/Net/Whois/Object/FilterSet/APNIC.pm 0214
lib/Net/Whois/Object/Inet6Num/AFRINIC.pm 0263
lib/Net/Whois/Object/Inet6Num/APNIC.pm 0265
lib/Net/Whois/Object/Inet6Num.pm 33
lib/Net/Whois/Object/InetNum/AFRINIC.pm 0264
lib/Net/Whois/Object/InetNum/APNIC.pm 0263
lib/Net/Whois/Object/InetNum.pm 11
lib/Net/Whois/Object/InetRtr/AFRINIC.pm 0226
lib/Net/Whois/Object/Information/AFRINIC.pm 051
lib/Net/Whois/Object/Irt/AFRINIC.pm 0261
lib/Net/Whois/Object/Irt/APNIC.pm 0261
lib/Net/Whois/Object/KeyCert/AFRINIC.pm 0205
lib/Net/Whois/Object/KeyCert/APNIC.pm 0208
lib/Net/Whois/Object/Limerick/AFRINIC.pm 0114
lib/Net/Whois/Object/Limerick.pm 11
lib/Net/Whois/Object/Mntner/AFRINIC.pm 0237
lib/Net/Whois/Object/Mntner/APNIC.pm 0242
lib/Net/Whois/Object/Organisation/AFRINIC.pm 0191
lib/Net/Whois/Object/Organisation/APNIC.pm 0194
lib/Net/Whois/Object/Organisation.pm 716
lib/Net/Whois/Object/PeeringSet/AFRINIC.pm 0143
lib/Net/Whois/Object/PeeringSet/APNIC.pm 0147
lib/Net/Whois/Object/PeeringSet.pm 11
lib/Net/Whois/Object/Person/AFRINIC.pm 0141
lib/Net/Whois/Object/Person/APNIC.pm 0145
lib/Net/Whois/Object/Person.pm 11
lib/Net/Whois/Object/Poem/APNIC.pm 0121
lib/Net/Whois/Object/Poem.pm 44
lib/Net/Whois/Object/PoeticForm/APNIC.pm 0100
lib/Net/Whois/Object/Role/AFRINIC.pm 0160
lib/Net/Whois/Object/Role/APNIC.pm 0163
lib/Net/Whois/Object/Route/AFRINIC.pm 0220
lib/Net/Whois/Object/Route/APNIC.pm 0224
lib/Net/Whois/Object/Route.pm 11
lib/Net/Whois/Object/Route6/AFRINIC.pm 0206
lib/Net/Whois/Object/Route6/APNIC.pm 0210
lib/Net/Whois/Object/RouteSet/AFRINIC.pm 0152
lib/Net/Whois/Object/RouteSet/APNIC.pm 0155
lib/Net/Whois/Object/RouteSet.pm 11
lib/Net/Whois/Object/RtrSet/AFRINIC.pm 0154
lib/Net/Whois/Object/RtrSet/APNIC.pm 0157
lib/Net/Whois/Object/RtrSet.pm 11
lib/Net/Whois/Object.pm 86179
lib/Net/Whois/RIPE.pm 5555
t/00-changes.t 04
t/02-methods.t 89
t/03-objects.t 2539
t/04-generic.t 0120
t/105-AsBlock.t 10
t/110-AutNum.t 11
t/115-Person.t 10
t/120-Role.t 10
t/125-AsSet.t 10
t/130-Domain.t 10
t/135-InetNum.t 10
t/140-Inet6Num.t 54
t/145-InetRtr.t 10
t/150-RtrSet.t 10
t/155-Mntner.t 10
t/160-KeyCert.t 10
t/165-Route.t 10
t/167-Route6.t 10
t/170-RouteSet.t 10
t/175-PeeringSet.t 12
t/180-Limerick.t 10
t/185-Poem.t 10
t/187-PoeticForm.t 10
t/190-Organisation.t 28
t/195-Response.t 10
t/200-Information.t 10
t/205-Irt.t 54
t/210-FilterSet.t 10
t/215-SyncUpdates.t 415
t/216-SyncUpdates-Signed.t 085
t/300-AFRINIC.t 027
t/305-APNIC.t 027
t/common.pl 30
97 files changed (This is a version diff) 2509700
@@ -1,5 +1,47 @@
 Revision history for net-whois-ripe
 
+            
+2.005003    2014-06-11
+            - Remove extra VERSION in Net::Whois::Generic
+            - Load Net::Whois::Generic with Net::Whois::RIPE (experimental)
+            - Clean tests (remove unneeded 'use Data::Dumper')
+            - Fix doc (to remove Net::Whois::Object->query() examples)
+
+2.005002    2014-06-09
+            - Deprecate Net::Whois::Object->query() (Net::Whois::Generic->query() is now recommended)
+
+2.005001    2013-10-11
+            - Add support for APNIC objects through Net::Whois::Generic
+            - Simplify query options handling in Net::Whois::Generic
+              (remove keepalive options)
+            - Start adding some documentation (far from enough although)
+
+2.005000    2013-10-10
+            - Add support for generic objects (from various sources, AFRINIC being the first implemented)
+              through Net::Whois::Generic
+
+2.004002    2013-07-31
+            - Add 'abuse_c' to AutNum object
+              (https://www.ripe.net/ripe/docs/ripe-563)
+
+2.004001    2013-06-19
+            - Remove Test::Exception requirement
+            - Add one test
+
+2.004000    2013-05-29
+            - Fix 'delete' mode on accessor
+            - Add awhois.pl skeleton script
+
+2.003000    2013-04-17
+            Another contribution from Moritz Lenz :
+            - Add abuse_c field to Organisation
+            - Inet6num has an attribute 'assignment_size'
+            - Unknown attributes in Object->new do not die anymore
+
+2.002000    2012-12-03
+            - Add 'delete' mode to attribute update
+            - Minor documentation fix
+
 2.001000    2012-11-22
             - Add the clone() method to Net::Whois::Object
             - Enhance accessor for multiple value attributes
@@ -1,39 +1,85 @@
+bin/awhois.pl
 Changes
+lib/Net/Whois/Generic.pm
 lib/Net/Whois/Object.pm
 lib/Net/Whois/Object/AsBlock.pm
+lib/Net/Whois/Object/AsBlock/AFRINIC.pm
+lib/Net/Whois/Object/AsBlock/APNIC.pm
 lib/Net/Whois/Object/AsSet.pm
+lib/Net/Whois/Object/AsSet/AFRINIC.pm
+lib/Net/Whois/Object/AsSet/APNIC.pm
 lib/Net/Whois/Object/AutNum.pm
+lib/Net/Whois/Object/AutNum/AFRINIC.pm
+lib/Net/Whois/Object/AutNum/APNIC.pm
 lib/Net/Whois/Object/Domain.pm
+lib/Net/Whois/Object/Domain/AFRINIC.pm
+lib/Net/Whois/Object/Domain/APNIC.pm
 lib/Net/Whois/Object/FilterSet.pm
+lib/Net/Whois/Object/FilterSet/AFRINIC.pm
+lib/Net/Whois/Object/FilterSet/APNIC.pm
 lib/Net/Whois/Object/Inet6Num.pm
+lib/Net/Whois/Object/Inet6Num/AFRINIC.pm
+lib/Net/Whois/Object/Inet6Num/APNIC.pm
 lib/Net/Whois/Object/InetNum.pm
+lib/Net/Whois/Object/InetNum/AFRINIC.pm
+lib/Net/Whois/Object/InetNum/APNIC.pm
 lib/Net/Whois/Object/InetRtr.pm
+lib/Net/Whois/Object/InetRtr/AFRINIC.pm
 lib/Net/Whois/Object/Information.pm
+lib/Net/Whois/Object/Information/AFRINIC.pm
 lib/Net/Whois/Object/Irt.pm
+lib/Net/Whois/Object/Irt/AFRINIC.pm
+lib/Net/Whois/Object/Irt/APNIC.pm
 lib/Net/Whois/Object/KeyCert.pm
+lib/Net/Whois/Object/KeyCert/AFRINIC.pm
+lib/Net/Whois/Object/KeyCert/APNIC.pm
 lib/Net/Whois/Object/Limerick.pm
+lib/Net/Whois/Object/Limerick/AFRINIC.pm
 lib/Net/Whois/Object/Mntner.pm
+lib/Net/Whois/Object/Mntner/AFRINIC.pm
+lib/Net/Whois/Object/Mntner/APNIC.pm
 lib/Net/Whois/Object/Organisation.pm
+lib/Net/Whois/Object/Organisation/AFRINIC.pm
+lib/Net/Whois/Object/Organisation/APNIC.pm
 lib/Net/Whois/Object/PeeringSet.pm
+lib/Net/Whois/Object/PeeringSet/AFRINIC.pm
+lib/Net/Whois/Object/PeeringSet/APNIC.pm
 lib/Net/Whois/Object/Person.pm
+lib/Net/Whois/Object/Person/AFRINIC.pm
+lib/Net/Whois/Object/Person/APNIC.pm
 lib/Net/Whois/Object/Poem.pm
+lib/Net/Whois/Object/Poem/APNIC.pm
 lib/Net/Whois/Object/PoeticForm.pm
+lib/Net/Whois/Object/PoeticForm/APNIC.pm
 lib/Net/Whois/Object/Response.pm
 lib/Net/Whois/Object/Role.pm
+lib/Net/Whois/Object/Role/AFRINIC.pm
+lib/Net/Whois/Object/Role/APNIC.pm
 lib/Net/Whois/Object/Route.pm
+lib/Net/Whois/Object/Route/AFRINIC.pm
+lib/Net/Whois/Object/Route/APNIC.pm
 lib/Net/Whois/Object/Route6.pm
+lib/Net/Whois/Object/Route6/AFRINIC.pm
+lib/Net/Whois/Object/Route6/APNIC.pm
 lib/Net/Whois/Object/RouteSet.pm
+lib/Net/Whois/Object/RouteSet/AFRINIC.pm
+lib/Net/Whois/Object/RouteSet/APNIC.pm
 lib/Net/Whois/Object/RtrSet.pm
+lib/Net/Whois/Object/RtrSet/AFRINIC.pm
+lib/Net/Whois/Object/RtrSet/APNIC.pm
 lib/Net/Whois/RIPE.pm
 Makefile.PL
 MANIFEST
 META.json			Module JSON meta-data (added by MakeMaker)
 META.yml			Module meta-data (added by MakeMaker)
 README
+README.md
+t/00-changes.t
 t/00-load.t
 t/01-instantiation.t
 t/02-methods.t
 t/03-objects.t
+t/04-generic.t
 t/105-AsBlock.t
 t/110-AutNum.t
 t/115-Person.t
@@ -59,7 +105,11 @@ t/200-Information.t
 t/205-Irt.t
 t/210-FilterSet.t
 t/215-SyncUpdates.t
+t/216-SyncUpdates-Signed.t
+t/300-AFRINIC.t
+t/305-APNIC.t
 t/boilerplate.t
 t/common.pl
 t/pod-coverage.t
 t/pod.t
+TODO
@@ -4,7 +4,7 @@
       "Luis Motta Campos <lmc@cpan.org>"
    ],
    "dynamic_config" : 1,
-   "generated_by" : "ExtUtils::MakeMaker version 6.6302, CPAN::Meta::Converter version 2.120921",
+   "generated_by" : "ExtUtils::MakeMaker version 6.6302, CPAN::Meta::Converter version 2.120630",
    "license" : [
       "unknown"
    ],
@@ -21,9 +21,7 @@
    },
    "prereqs" : {
       "build" : {
-         "requires" : {
-            "Test::Exception" : "0"
-         }
+         "requires" : {}
       },
       "configure" : {
          "requires" : {
@@ -50,5 +48,5 @@
          "url" : "https://github.com/arhuman/Net-Whois-RIPE"
       }
    },
-   "version" : "2.001"
+   "version" : "2.005003"
 }
@@ -2,12 +2,11 @@
 abstract: 'a pure-Perl implementation of the RIPE Database client.'
 author:
   - 'Luis Motta Campos <lmc@cpan.org>'
-build_requires:
-  Test::Exception: 0
+build_requires: {}
 configure_requires:
   ExtUtils::MakeMaker: 0
 dynamic_config: 1
-generated_by: 'ExtUtils::MakeMaker version 6.6302, CPAN::Meta::Converter version 2.120921'
+generated_by: 'ExtUtils::MakeMaker version 6.6302, CPAN::Meta::Converter version 2.120630'
 license: unknown
 meta-spec:
   url: http://module-build.sourceforge.net/META-spec-v1.4.html
@@ -26,4 +25,4 @@ requires:
 resources:
   bugtracker: https://github.com/arhuman/Net-Whois-RIPE/issues
   repository: https://github.com/arhuman/Net-Whois-RIPE
-version: 2.001
+version: 2.005003
@@ -22,7 +22,7 @@ WriteMakefile(
                         bugtracker => 'https://github.com/arhuman/Net-Whois-RIPE/issues'
         },
     },
-    BUILD_REQUIRES => { 'Test::Exception' => 0, },
+    BUILD_REQUIRES => { },
     dist           => { COMPRESS          => 'gzip -9f', SUFFIX => 'gz', },
     clean          => { FILES             => 'Net-Whois-RIPE-*' },
 );
@@ -0,0 +1,42 @@
+# Net::Whois::RIPE
+
+A pure-perl programming interface to the RIPE Database Whois service.
+
+This is a complete rewrite of the old version of the module Luis Motta Campos inherited from
+Paul Gampe. 
+
+This repository (try to) follow the git-flow development model, so please use the 'develop' branch
+for your work/pull request.
+
+## INSTALLATION
+
+To install this module, run the following commands:
+
+	perl Makefile.PL
+	make
+	make test
+	make install
+
+## SUPPORT AND DOCUMENTATION
+
+After installing, you can find documentation for this module with the
+perldoc command.
+
+    perldoc Net::Whois::RIPE
+
+You can also look for information at:
+
+    GitHub.
+        https://github.com/arhuman/Net-Whois-RIPE
+
+
+    Search CPAN
+        http://search.cpan.org/dist/net-whois-ripe
+
+## COPYRIGHT AND LICENCE
+
+Copyright (C) 2010 Luis Motta Campos
+
+This program is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
@@ -0,0 +1,8 @@
+* check http://cpants.cpanauthors.org/dist/Net-Whois-RIPE errors
+* use strict; use warnings; everywhere...
+* check abuse-c/abuse-mailbox status 
+* add option to query to get unfiltered data (-B on RIPE) and check for mail on aassad-ripe
+ (make it default ?)
+* change hardcoded options on query to non RIPE sources (use RIPE model)
+* Add more usage examples
+* Add read/write of RIPE objects of each type on test DB to test for templates changes ('status' attribute on Aut-Num...)
@@ -0,0 +1,150 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use Getopt::Long;
+use Net::Whois::Generic;
+use Data::Dumper;
+
+####################################################################################
+#
+# Global variables
+
+my $DEBUG;
+my @EXCLUDES;
+my $HELP;
+my $KEY;
+my $ONLY;
+my $QUERY;
+my %QUERY_OPTIONS;
+my @TYPES;
+my $VERSION;
+
+####################################################################################
+#
+# Processing
+
+# Get options value from command line
+GetOptions( 'debug'      => \$DEBUG,
+            'excludes=s' => \@EXCLUDES,
+            'help'       => \$HELP,
+            'key=s'      => \$KEY,
+            'only=s'     => \$ONLY,
+            'query=s'    => \$QUERY,
+            'type=s'     => \@TYPES,
+            'version'    => \$VERSION,
+) or die usage();
+
+if ($HELP) {
+    print usage();
+    exit 0;
+}
+
+if ($VERSION) {
+    print "$0  -  using Net::Whois::RIPE $Net::Whois::RIPE::VERSION\n";
+    exit 0;
+}
+
+# Query can be implicit or explicit
+$QUERY = $ARGV[0] unless $QUERY;
+
+# You can now do
+if (@TYPES) {
+    my $query_types = lc join '|', @TYPES;
+    $query_types =~ s/-//g;
+    $QUERY_OPTIONS{type} = $query_types;
+}
+
+if ($KEY) {
+    $QUERY = "-i $KEY " . $ARGV[0] unless $QUERY =~ /-i/;
+}
+
+if ($DEBUG) {
+    print "QUERY=($QUERY)\n";
+    print "OPTIONS=", Dumper \%QUERY_OPTIONS;
+}
+
+my @objects = Net::Whois::Generic->query( $QUERY, \%QUERY_OPTIONS );
+
+# And manipulate the object the OO ways
+for my $object (@objects) {
+    print $object->dump;
+    print $/;
+}
+
+exit 0;
+
+sub excluded {
+    my $tested = shift;
+
+    return 0 unless @EXCLUDES;
+
+    if ($ONLY) {
+        return 1 unless $tested =~ /$ONLY/msi;
+    }
+
+    for my $ex_pattern (@EXCLUDES) {
+        return 1 if $tested =~ /$ex_pattern/msi;
+    }
+
+    return 0;
+}
+
+sub usage {
+
+    return <<EOT;
+
+NAME
+
+    $0 - WHOIS client for RIPE database
+
+SYNOPSIS
+
+    $0 [options] [query ...]
+
+    # Get objects whose maintener is JAGUAR-MNT
+    $0 --key mnt-by JAGUAR-MNT
+
+    # Get objects about ASN 30781
+    $0 AS30781
+
+
+OPTIONS
+
+
+--help
+
+    Print a brief help message and exits.
+
+--debug
+
+    Display debugging information
+
+--exclude
+
+    Not yet implemented
+
+--key
+
+    The attribute to be used as the key for the search
+
+--only
+
+    Not yet implemented
+
+--type
+
+    The type of record to be returned (example: person, role, inetnum, route...)
+
+--version
+
+    Display version information
+
+
+DESCRIPTION
+
+This program is a WHOIS client requesting the RIPE database
+
+EOT
+}
+
@@ -0,0 +1,735 @@
+package Net::Whois::Generic;
+
+use 5.006;
+use warnings;
+use strict;
+use IO::Socket::INET;
+use IO::Select;
+use Iterator;
+use Net::Whois::Object;
+use Data::Dumper;
+
+use constant {
+	SOON               => 30,
+	END_OF_OBJECT_MARK => "\n\n",
+	EOL                => "\015\012",
+	QUERY_LIST_OBJECTS => q{-qtypes },
+};
+
+# simplify if all servers happen to accept same options
+our %RIR = (
+	apnic   => { SERVER => 'whois.apnic.net',   QUERY_NON_RECURSIVE => q{-r }, QUERY_REFERRAL => q{-R }, QUERY_UNFILTERED => q{-B }, },
+	ripe    => { SERVER => 'whois.ripe.net',    QUERY_NON_RECURSIVE => q{-r }, QUERY_REFERRAL => q{-R }, QUERY_UNFILTERED => q{-B }, },
+	arin    => { SERVER => 'whois.arin.net',    QUERY_NON_RECURSIVE => q{-r }, QUERY_REFERRAL => q{-R }, QUERY_UNFILTERED => q{-B }, },
+	lacnic  => { SERVER => 'whois.lacnic.net',  QUERY_NON_RECURSIVE => q{-r }, QUERY_REFERRAL => q{-R }, QUERY_UNFILTERED => q{-B }, },
+	afrinic => { SERVER => 'whois.afrinic.net', QUERY_NON_RECURSIVE => q{-r }, QUERY_REFERRAL => q{-R }, QUERY_UNFILTERED => q{-B }, },
+);
+
+=head1 NAME
+
+Net::Whois::Generic - a pure-Perl implementation of a multi source Whois client.
+
+=head1 SYNOPSIS
+
+Net::Whois::Generic is my first attempt to unify Whois information from different sources.
+Historically Net::Whois::RIPE was the first written, then Net::Whois::Object was added to provide
+a RPSL encapsultation of the data returned from RIPE database, with an API more object oriented.
+
+Net::Whois::Generic is a new interface designed to be more generic and to encapsulate data from 
+various sources (RIPE, but also AFRINIC, APNIC...)
+The current implementation is barely a proof of concept, AFRINIC and APNIC are the only other sources implemented,
+but I expect to turn it into a generic/robust implementation based on the users feedback.
+
+    my $c = Net::Whois::Generic->new( disconnected => 1, unfiltered => 1 );
+
+    my ($org) = $c->query( 'ORG-AFNC1-AFRINIC', { type => 'organisation' } );
+    # $org is a 'Net::Whois::Object::Organisation::AFRINIC' object;
+    
+    my @o = $c->query('101.0.0.0/8');
+    # @o contains various Net::Whois::Object:Inetnum::APNIC, and Net::Whois::Object::Information objects
+
+As Net::Whois::Generic started as an improvment of Net::Whois::RIPE, and have a good amount of code in common,
+for this reason (and some others) it is currently bundled inside the the Net::Whois::RIPE package.
+This might change in the future although.
+
+=head1 METHODS
+
+=head2 B<new( %options )>
+
+Constructor. Returns a new L<Net::Whois::Generic> object with an open connection
+to the RIPE Database service of choice (defaulting to C<whois.ripe.net:43>).
+
+The C<%options> hash migth contain configuration options for the RIPE Database
+server. Not all options provided by the RIPE Database server are suitable for
+this implementation, but the idea is to provide everything someone can show a
+use for. The options currently recognized are:
+
+=over 4
+
+=item B<hostname>  (IPv4 address or DNS name. Default is C<whois.ripe.net>)
+
+The hostname or IP address of the service to connect to
+
+=item B<port> (integer, default is C<43>)
+
+The TCP port of the service to connect to
+
+=item B<timeout> (integer, default is C<5>)
+
+The time-out (in seconds) for the TCP connection.
+
+=item B<referral> (boolean, default is C<false>)
+
+When true, prevents the server from using the referral mechanism for domain
+lookups, so that the RIPE Database server returns an object in the RIPE
+Database with the exact match with the lookup argument, rather than doing a
+referral lookup.
+
+=item B<recursive> (boolean, default is C<false>)
+
+When set to C<true>, prevents recursion into queried objects for personal
+information. This prevents lots of unsolicited objects from showing up on
+queries.
+
+=item B<grouping> (boolean, default is C<false>)
+
+When C<true> enables object grouping in server responses. There's little
+utility to enable this option, as the objects will be parsed and returned on a
+much reasonable format most of the time. For the brave or more knowledgeable
+people that want to have they answers in plain text, this can help stablishing
+a 'good' ordering for the RPSL objects returned by a query ('good' is RIPE
+NCC's definition of 'good' in this case).
+
+=item B<unfiltered> (boolean, default is C<false>)
+
+When C<true> enables unfiltered object output responses. This produces objects
+that can be presented back to the RIPE Database for updating.
+
+=item B<types> (list of valid RIPE Database object types, default is empty, meaning all types)
+
+Restrict the RPSL object types allowed in the response to those in the list.
+Using this option will cause the L<Net::Whois::Generic> object to query the RIPE
+Database for the available object types for validating the list. The response
+will be cached for speed and bandwidth.
+
+=item B<disconnected> (boolean, default is C<false>)
+
+Prevents the constructor from automatically opening a connection to the service
+specified (conneting the socket is the default behavior). When set (C<true>),
+the programmer is responsible for calling C<connect> in order to stablish a
+connection to the RIPE Database service desired.
+
+=back
+
+=cut
+
+{
+	my %default_options = (
+		hostname     => 'whois.ripe.net',
+		port         => '43',
+		timeout      => 5,
+		referral     => 0,
+		recursive    => 0,
+		grouping     => 1,
+		unfiltered   => 0,
+		types        => undef,
+		disconnected => 0,
+	);
+
+	sub new
+	{
+		my $class = shift;
+
+		# I wish I hadn't to maintain backward compatibility but 2 forms exist...
+		my %options;
+
+		if (ref($_[0]) =~ /HASH/i) {
+			%options = %{ $_[0] };
+		}
+		else {
+			%options = @_;
+		}
+		my %known_options;
+		$known_options{$_} = exists $options{$_} ? $options{$_} : $default_options{$_} foreach keys %default_options;
+
+		my $self = bless { __options => \%known_options }, $class;
+
+		return $self;
+	}
+}
+
+=head2 B<hostname( [$hostname] )>
+
+Accessor to the hostname. Accepts an optional hostname, always return the
+current hostname.
+
+=cut
+
+sub hostname
+{
+	my ($self, $hostname) = @_;
+	$self->{__options}{hostname} = $hostname if defined $hostname;
+	return $self->{__options}{hostname};
+}
+
+=head2 B<port()>
+
+Accessor to the port. Accepts an optional port, always return the current
+port.
+
+=cut
+
+sub port
+{
+	my ($self, $port) = @_;
+	$self->{__options}{port} = $port if defined $port && $port =~ m{^\d+$};
+	return $self->{__options}{port};
+}
+
+=head2 B<timeout()>
+
+Accessor to the timeout configuration option. Accepts an optional timeout,
+always return the current timeout.
+
+=cut
+
+sub timeout
+{
+	my ($self, $timeout) = @_;
+	$self->{__options}{timeout} = $timeout
+		if defined $timeout && $timeout =~ m{^\d+$};
+	return $self->{__options}{timeout};
+}
+
+=begin UNDOCUMENTED
+
+=head2 B<__boolean_accessor( $self, $attribute [, $value ] )>
+
+Private method. Shouldn't be used from other modules.
+
+Generic implementation of an accessor for booleans. Receives a reference to the
+current instance, the attribute name, and a value to be interpreted under
+Perl's boolean rules. Sets or gets the named attribute with the given value.
+Always returns the most up-to-date value of the attribute.
+
+=end UNDOCUMENTED
+
+=cut
+
+sub __boolean_accessor
+{
+	my ($self, $attribute) = (shift, shift);
+	if (scalar @_ == 1) {
+		my $value = shift;
+		$self->{__options}{$attribute} = $value ? 1 : 0;
+	}
+	return $self->{__options}{$attribute};
+}
+
+=head2 B<referral()>
+
+Accessor to the referral configuration option. Accepts an optional referral,
+always return the current referral.
+
+=cut
+
+sub referral
+{
+	my $self = shift;
+	return $self->__boolean_accessor('referral', @_);
+}
+
+=head2 B<recursive()>
+
+Accessor to the recursive configuration option. Accepts an optional recursive,
+always return the current recursive.
+
+=cut
+
+sub recursive
+{
+	my $self = shift;
+	return $self->__boolean_accessor('recursive', @_);
+}
+
+=head2 B<grouping()>
+
+Accessor to the grouping configuration option. Accepts an optional grouping,
+always return the current grouping.
+
+=cut
+
+sub grouping
+{
+	my $self = shift;
+	return $self->__boolean_accessor('grouping', @_);
+}
+
+=head2 B<unfiltered()>
+
+Accessor to the unfiltered configuration option.
+
+=cut
+
+sub unfiltered
+{
+	my $self = shift;
+	return $self->__boolean_accessor('unfiltered', @_);
+}
+
+=head2 B<connect()>
+
+Initiates a connection with the current object's configuration.
+
+=cut
+
+sub connect
+{
+	my $self       = shift;
+	my %connection = (
+		Proto      => 'tcp',
+		Type       => SOCK_STREAM,
+		PeerAddr   => $self->hostname,
+		PeerPort   => $self->port,
+		Timeout    => $self->timeout,
+		Domain     => AF_INET,
+		Multihomed => 1,
+	);
+
+	# Create a new IO::Socket object
+	my $socket = $self->{__state}{socket} = IO::Socket::INET->new(%connection);
+	die q{Can't connect to "} . $self->hostname . ':' . $self->port . qq{". Reason: [$@].\n}
+		unless defined $socket;
+
+	# Register $socket with the IO::Select object
+	if (my $ios = $self->ios) {
+		$ios->add($socket) unless $ios->exists($socket);
+	}
+	else {
+		$self->{__state}{ioselect} = IO::Select->new($socket);
+	}
+}
+
+=head2 B<ios()>
+
+Accessor to the L<IO::Select> object coordinating the I/O to the L<IO::Socket>
+object used by this module to communicate with the RIPE Database Server. You
+shouldn't use this object, but the L</"send()"> and L<"query( $query_string )">
+methods instead.
+
+=cut
+
+sub ios { return $_[0]->{__state}{ioselect} }
+
+=head2 B<socket()>
+
+Read-only accessor to the L<IO::Socket> object used by this module.
+
+=cut
+
+sub socket { return $_[0]->{__state}{socket} }
+
+=head2 B<send()>
+
+Sends a message to the RIPE Database server instance to which we're connected
+to. Dies if it cannot write, or if there's no open connection to the server.
+
+Return C<true> if the message could be written to the socket, C<false>
+otherwise.
+
+=cut
+
+sub send
+{
+	my ($self, $message) = @_;
+	die q{Not connected} unless $self->is_connected;
+	if ($self->ios->can_write(SOON + $self->timeout)) {
+		$self->socket->print($message, EOL);
+		$self->socket->flush;
+		return 1;
+	}
+	return 0;
+}
+
+=head2 B<reconnect()>
+
+Reconnects to the server in case we lost connection.
+
+=cut
+
+sub reconnect
+{
+	my $self = shift;
+	$self->disconnect if $self->is_connected;
+	$self->connect;
+}
+
+=head2 B<disconnect()>
+
+Disconnects this client from the server. This renders the client useless until
+you call L</"connect()"> again. This method is called by L</DESTROY()> as part of
+an object's clean-up process.
+
+=cut
+
+sub disconnect
+{
+	my $self = shift;
+	if ($self->is_connected) {
+		my $socket = $self->{__state}{socket};
+		$socket->close;
+		$self->{__state}{ioselect}->remove($socket)
+			if $self->{__state}{ioselect};
+		delete $self->{__state}{socket};
+	}
+}
+
+=head2 B<is_connected()>
+
+Returns C<true> if this instance is connected to the RIPE Database service
+configured.
+
+=cut
+
+sub is_connected
+{
+	my $self   = shift;
+	my $socket = $self->socket;
+	return UNIVERSAL::isa($socket, 'IO::Socket')
+		&& $socket->connected ? 1 : 0;
+}
+
+=head2 B<DESTROY()>
+
+Net::Whois::Generic object destructor. Called by the Perl interpreter upon
+destruction of an instance.
+
+=cut
+
+sub DESTROY
+{
+	my $self = shift;
+	$self->disconnect;
+}
+
+=head2 B<_find_rir( $query_string )>
+
+Guess the associated RIR based on the query.
+
+=cut
+
+sub _find_rir
+{
+	my ($self, $query) = @_;
+
+	my $rir;
+
+	if (       ($query =~ /^(41|102|105|154|196|197)\.\d+\.\d+\.\d+/)
+		or ($query =~ /AFRINIC/i)
+		or ($query =~ /^2c00::/i))
+	{
+		$rir = 'afrinic';
+	}
+	elsif ( (          $query =~ /^(23|34|50|64|64|65|66|67|68|69|70|71|72|73|74|75|76|96|97|98|9|100|104|107|108|135|136|142|147|162|166|172|173|174|184|192|198|199|204|205|206|207|208|209|216)/
+			or ($query =~ /^(2001:0400|2001:1800|2001:4800:|2600|2610:0000):/i)
+			or $query =~ /ARIN/
+		)
+		)
+	{
+		$rir = 'arin';
+
+	}
+	elsif ( (          $query =~ /^(10|14|27|36|39|42|49|58|59|60|61|101|103|106|110|111|112|113|114|115|116|117|118|119|120|121|122|123|124|125|126|169\.208|175|180|182|183|202|203|210|211|218|219|220|221|222|223)\.\d+\.\d+/
+			or ($query =~ /^(2001:0200|2001:0C00|2001:0E00|2001:4400|2001:8000|2001:A000|2001:B000|2400:0000|2001:0DC0|2001:0DE8|2001:0DF0|2001:07FA|2001:0DE0|2001:0DB8):/i)
+			or $query =~ /APNIC/
+		)
+		)
+	{
+		$rir = 'apnic';
+
+	}
+	else {
+		$rir = 'ripe';
+	}
+
+	return $rir;
+}
+
+=head2 B<adapt_query( $query_string[, $rir] )>
+
+Adapt a query to set various parameter (whois server, query options...) based on the query.
+Takes an optional parameter $rir, to force a specific RIR to be used.
+
+=cut
+
+sub adapt_query
+{
+	my ($self, $query, $rir) = @_;
+	my $fullquery;
+
+	# determine RIR unless $rir;
+	$rir = $self->_find_rir($query) unless $rir;
+
+	if ($rir eq 'ripe') {
+		$self->hostname($RIR{ripe}{SERVER});
+	}
+	elsif ($rir eq 'afrinic') {
+		$fullquery = '-V Md5.0 ' . $query;
+		$self->hostname($RIR{afrinic}{SERVER});
+	}
+	elsif ($rir eq 'arin') {
+		$self->hostname($RIR{arin}{SERVER});
+	}
+	elsif ($rir eq 'lacnic') {
+		$self->hostname($RIR{lacnic}{SERVER});
+	}
+	elsif ($rir eq 'apnic') {
+		$self->hostname($RIR{apnic}{SERVER});
+	}
+
+	my $parameters = "";
+	$parameters .= q{ } . $RIR{$rir}{QUERY_UNFILTERED} if $self->unfiltered;
+	$parameters .= q{ } . $RIR{$rir}{QUERY_NON_RECURSIVE} unless $self->recursive;
+	$parameters .= q{ } . $RIR{$rir}{QUERY_REFERRAL} if $self->referral;
+	$fullquery = $parameters . $query;
+
+	return $fullquery;
+}
+
+=head2 B<query( $query, [\%options] )>
+
+ ******************************** EXPERIMENTAL ************************************
+   This method is a work in progress, the API and behaviour are subject to change
+ **********************************************************************************
+
+Query the the appropriate RIR database and return Net::Whois::Objects
+
+This method accepts 2 optional parameters
+
+'type' which is a regex used to filter the query result:
+Only the object whose type matches the 'type' parameter are returned
+
+'attribute' which is a regex used to filter the query result:
+Only the value of the attributes matching the 'attribute' parameter are
+returned
+
+Note that if 'attribute' is specified strings are returned, instead of
+Net::Whois::Objects
+
+Net::Whois:Generic->query() deprecates  Net::Whois::Object->query() since release 2.005 of Net::Whois::RIPE
+
+=cut
+
+sub query
+{
+	my ($self, $query, $options) = @_;
+
+	my $attribute;
+	my $type;
+	my $response;
+
+	for my $opt (keys %$options) {
+		if ($opt =~ /^attribute$/i) {
+			$attribute = $options->{$opt};
+		}
+		elsif ($opt =~ /^type$/i) {
+			$type = $options->{$opt};
+		}
+	}
+
+	if (!ref $self) {
+
+		# $self is the class
+		$self = $self->new($options);
+	}
+
+	$query = $self->adapt_query($query);
+	my $iterator = $self->__query($query);
+
+	my @objects = Net::Whois::Object->new($iterator);
+
+	($response) = grep { ref($_) =~ /response/i } @objects;
+
+	if ($response) {
+		$self->_process_response($response);
+
+	}
+
+	if ($type) {
+		@objects = grep { ref($_) =~ /$type/i } @objects;
+	}
+
+	if ($attribute) {
+		return grep {defined} map {
+			my $r;
+			eval { $r = $_->$attribute };
+			$@ ? undef : ref($r) eq 'ARRAY' ? @$r : $r
+		} @objects;
+	}
+	else {
+		return grep {defined} @objects;
+	}
+}
+
+# Allows me to pass in queries without having all the automatic options added
+# up to it.
+sub __query
+{
+	my ($self, $query) = @_;
+
+	$self->connect;
+
+	# die "Not connected" unless $self->is_connected;
+
+	if ($self->ios->can_write(SOON + $self->timeout)) {
+		$self->socket->print($query, EOL);
+
+		return Iterator->new(
+			sub {
+				local $/ = END_OF_OBJECT_MARK;
+				if ($self->ios->can_read(SOON + $self->timeout)) {
+					my $block = $self->socket->getline;
+					return $block if defined $block;
+				}
+				Iterator::is_done;
+			}
+		);
+	}
+}
+
+=head2 B<object_types()>
+
+Return a list of known object types from the RIPE Database.
+
+RIPE currently returns 21 types (Limerik have been removed):
+as-block as-set aut-num domain filter-set inet6num inetnum inet-rtr irt
+key-cert mntner organisation peering-set person poem poetic-form role route
+route6 route-set rtr-set
+
+Due to some strange mis-behaviour in the protocol (or documentation?) the RIPE
+Database server won't allow a keep-alive token with this query, meaning the
+connection will be terminated after this query.
+
+=cut
+
+sub object_types
+{
+	my $self     = shift;
+	my $iterator = $self->__query(QUERY_LIST_OBJECTS);
+	while (!$iterator->is_exhausted) {
+		my $value = $iterator->value;
+		return split /\s+/, $value if $value !~ /^%\s/;
+	}
+	return;
+}
+
+=head2 B<_process_response( $response )>
+
+Process a response (error code, error message...)
+
+=cut
+
+sub _process_response
+{
+	my $self     = shift;
+	my $response = shift;
+	my $code;
+	my $msg;
+
+	eval { $response->comment };
+	die "Dump : " . Dumper $response if $@;
+
+	if ($response->response =~ /ERROR.*:.*?(\d+)/) {
+		$code = $1;
+		$msg = join '', $response->comment();
+	}
+}
+
+=head1 AUTHOR
+
+Arnaud "Arhuman" Assad, C<< <arhuman at gmail.com> >>
+
+=head1 CAVEATS
+
+=over 4
+
+=item B<Update>
+
+Update of objects from database other than RIPE is not currently implemented...
+
+=item B<Sources>
+
+Currently the only sources implemented are RIPE, AFRINIC, and APNIC.
+
+=item B<Maturity>
+
+The Net::Whois::Generic interface is highly experimental.
+There are probably bugs, without any doubt missing documentation and
+examples but please don't hesitate to contact me to suggest corrections
+and improvments.
+
+=back
+
+=head1 BUGS
+
+Please report any bugs or feature requests to C<bug-net-whois-ripe at
+rt.cpan.org>, or through the web interface at
+L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=net-whois-ripe>.  I will be
+notified, and then you'll automatically be notified of progress on your bug as
+I make changes.
+
+=head1 SEE ALSO
+
+There are several tools similar to L<Net::Whois::Generic>, I'll list some of them below and some reasons why Net::Whois::Generic exists anyway:
+
+L<Net::Whois::IANA> - A universal WHOIS extractor: update not possible, no RPSL parser
+
+L<Net::Whois::ARIN> - ARIN whois client: update not possible, only subset of ARIN objects handled
+
+L<Net::Whois::Parser> - Module for parsing whois information: no query handling, parser can (must?) be added
+
+L<Net::Whois::RIPE> - RIPE whois client: the basis for L<Net::Whois::Generic> but only handle RIPE.
+   
+=head1 SUPPORT
+
+You can find documentation for this module with the perldoc command.
+
+    perldoc Net::Whois::Generic
+
+You can also look for information at:
+
+=over 4
+
+=item * RT: CPAN's request tracker
+
+L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=net-whois-ripe>
+
+=item * AnnoCPAN: Annotated CPAN documentation
+
+L<http://annocpan.org/dist/net-whois-ripe>
+
+=item * CPAN Ratings
+
+L<http://cpanratings.perl.org/d/net-whois-ripe>
+
+=item * Search CPAN
+
+L<http://search.cpan.org/dist/net-whois-ripe>
+
+=back
+
+
+=head1 ACKNOWLEDGEMENTS
+
+Thanks to Jaguar Networks which grants me time to work on this module.
+
+=head1 COPYRIGHT & LICENSE
+
+Copyright 2013 Arnaud "Arhuman" Assad, all rights reserved.
+
+This program is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=cut
+
+1;
@@ -0,0 +1,181 @@
+package Net::Whois::Object::AsBlock::AFRINIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -t as-block -h whois.afrinic.net
+# % This is the AfriNIC Whois server.
+# 
+# as-block:       [mandatory]  [single]     [primary/look-up key]
+# descr:          [optional]   [multiple]   [ ]
+# remarks:        [optional]   [multiple]   [ ]
+# org:            [optional]   [multiple]   [inverse key]
+# admin-c:        [mandatory]  [multiple]   [inverse key]
+# tech-c:         [mandatory]  [multiple]   [inverse key]
+# notify:         [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [multiple]   [inverse key]
+# mnt-lower:      [optional]   [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+
+
+__PACKAGE__->attributes( 'primary', ['as_block'] );
+__PACKAGE__->attributes( 'mandatory', [ 'as_block', 'admin_c', 'tech_c', 'mnt_by', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional', [ 'descr', 'remarks', 'org', 'notify', 'mnt_lower' ] );
+__PACKAGE__->attributes( 'single', [ 'as_block', 'source' ] );
+__PACKAGE__->attributes( 'multiple', [ 'descr', 'remarks', 'org', 'admin_c', 'tech_c', 'notify', 'mnt_lower', 'mnt_by', 'changed' ] );
+
+=head1 NAME
+
+Net::Whois::Object::AsBlock::AFRINIC - an object representation of the RPSL AsBlock block
+
+=head1 DESCRIPTION
+
+An as-block object is needed to delegate a range of AS numbers to a
+given repository.  This object may be used for authorisation of the
+creation of aut-num objects within the range specified by the
+"as-block:" attribute.
+
+=head1 METHODS
+
+=head2 B<new( %options )>
+
+Constructor for the Net::Whois::Object::AsBlock::AFRINIC class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+
+    return $self;
+}
+
+=head2 B<as_block( [$as_block] )>
+
+Accessor to the as_block attribute.
+Accepts an optional as_block, always return the current as_block value.
+
+An as_block is a range of AS numbers delegated to a Regional or National Internet Registry
+(NIR).
+
+The AS numbers in the range are subsequently assigned by the registry to
+members or end-users in the region.
+Information on individual AS numbers within an as-block object are
+stored in the appropriate Internet Registry's Whois Database.
+
+=head2 B<descr( [$descr] )>
+
+Accessor to the descr attribute.
+Accepts an optional descr, always return the current descr value.
+
+Description of the Internet Registry delegated the range of AS numbers shown
+in the as-block.
+
+=head2 B<remarks( [$remarks] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remarks to be added to the remarks array,
+always return the current remarks array.
+
+Information on the registry that maintains details of AS numbers assigned from
+the as-block.
+
+Also includes where to direct a whois client to find further information on
+the AS numbers.
+
+=head2 B<tech_c( [$tech_c] )>
+
+Accessor to the tech_c attribute.
+Accepts an optional tech_c to be added to the tech_c array,
+always return the current tech_c array.
+
+The NIC-handle of a technical contact 'person' or 'role' object.  As more than
+one person often fulfills a role function, there may be more than one tech-c
+listed.
+
+A technical contact (tech-c) must be a person responsible for the
+day-to-day operation of the network, but does not need to be
+physically located at the site of the network.
+
+
+=head2 B<admin_c( [$admin_c])>
+
+Accessor to the admin_c attribute.
+Accepts an optional admin_c to be added to the admin_c array,
+always return the current admin_c array.
+
+The NIC-handle of an on-site contact 'person' object. As more than one person
+often fulfills a role function, there may be more than one admin-c listed.
+
+An administrative contact(admin-c) must be someone who is physically
+located at the site of the network.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional value to be added notify array,
+        always return the current notify array.
+
+The email address to which notifications of changes 
+to the object should be sent.
+
+=head2 B<mnt_lower( [$mnt_lower] )>
+
+Accessor to the mnt_lower attribute.
+Accepts an optional mnt_lower value to be added to the mnt_lower array,
+always return the current mnt_lower array.
+
+The identifier of a registered 'mntner' object used to authorize the creation
+of 'aut-num' objects within the range specified by the as-block.
+
+If no 'mnt-lower' is specified, the 'mnt-by' attribute is used for
+authorization.
+
+=head2 B<mnt_by( [$mnt_by] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+always return the current mnt_by array.
+
+Lists a registered 'mntner' used to authorize and authenticate changes to this
+object.
+
+When your database details are protected by a 'mntner' object, then
+only persons with access to the security information of that 'mntner'
+object will be able to change details.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+The email address of who last updated the database object and the date it
+occurred.
+
+Every time a change is made to a database object, this attribute will show
+the email address of the person who made those changes.
+Please use the address format specified in RFC 822 - Standard for
+the Format of ARPA Internet Text Message and provide the date
+format using one of the following two formats: YYYYMMDD or YYMMDD.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+The database where the object is registered.
+
+=head2 B<org( [$org] )>
+
+Accessor to the org attribute.
+Accepts an optional org, always return the current org.
+
+The organisation entity this object is bound to.
+
+=cut
+
+1;
@@ -0,0 +1,184 @@
+package Net::Whois::Object::AsBlock::APNIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -h whois.apnic.net -t as-block
+# % [whois.apnic.net]
+# % Whois data copyright terms    http://www.apnic.net/db/dbcopyright.html
+# 
+# as-block:       [mandatory]  [single]     [primary/lookup key]
+# descr:          [optional]   [multiple]   [ ]
+# remarks:        [optional]   [multiple]   [ ]
+# country:        [optional]   [single]     [ ]
+# admin-c:        [mandatory]  [multiple]   [inverse key]
+# tech-c:         [mandatory]  [multiple]   [inverse key]
+# org:            [optional]   [multiple]   [inverse key]
+# notify:         [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [multiple]   [inverse key]
+# mnt-lower:      [optional]   [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+
+% This query was served by the APNIC Whois Service version 1.68.5 (WHOIS1)
+
+__PACKAGE__->attributes( 'primary', ['as_block'] );
+__PACKAGE__->attributes( 'mandatory', [ 'as_block', 'admin_c', 'tech_c', 'mnt_by', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional', [ 'descr', 'remarks', 'country', 'org', 'notify', 'mnt_lower' ] );
+__PACKAGE__->attributes( 'single', [ 'as_block', 'country', 'source' ] );
+__PACKAGE__->attributes( 'multiple', [ 'descr', 'remarks', 'admin_c', 'tech_c', 'org', 'notify', 'mnt_by', 'mnt_lower', 'changed' ] );
+
+=head1 NAME
+
+Net::Whois::Object::AsBlock::APNIC - an object representation of the RPSL AsBlock block
+
+=head1 DESCRIPTION
+
+An as-block object is needed to delegate a range of AS numbers to a
+given repository.  This object may be used for authorisation of the
+creation of aut-num objects within the range specified by the
+"as-block:" attribute.
+
+=head1 METHODS
+
+=head2 B<new( %options )>
+
+Constructor for the Net::Whois::Object::AsBlock::APNIC class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+
+    return $self;
+}
+
+=head2 B<as_block( [$as_block] )>
+
+Accessor to the as_block attribute.
+Accepts an optional as_block, always return the current as_block value.
+
+An as_block is a range of AS numbers delegated to a Regional or National Internet Registry
+(NIR).
+
+The AS numbers in the range are subsequently assigned by the registry to
+members or end-users in the region.
+Information on individual AS numbers within an as-block object are
+stored in the appropriate Internet Registry's Whois Database.
+
+=head2 B<descr( [$descr] )>
+
+Accessor to the descr attribute.
+Accepts an optional descr, always return the current descr value.
+
+Description of the Internet Registry delegated the range of AS numbers shown
+in the as-block.
+
+=head2 B<remarks( [$remarks] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remarks to be added to the remarks array,
+always return the current remarks array.
+
+Information on the registry that maintains details of AS numbers assigned from
+the as-block.
+
+Also includes where to direct a whois client to find further information on
+the AS numbers.
+
+=head2 B<tech_c( [$tech_c] )>
+
+Accessor to the tech_c attribute.
+Accepts an optional tech_c to be added to the tech_c array,
+always return the current tech_c array.
+
+The NIC-handle of a technical contact 'person' or 'role' object.  As more than
+one person often fulfills a role function, there may be more than one tech-c
+listed.
+
+A technical contact (tech-c) must be a person responsible for the
+day-to-day operation of the network, but does not need to be
+physically located at the site of the network.
+
+
+=head2 B<admin_c( [$admin_c])>
+
+Accessor to the admin_c attribute.
+Accepts an optional admin_c to be added to the admin_c array,
+always return the current admin_c array.
+
+The NIC-handle of an on-site contact 'person' object. As more than one person
+often fulfills a role function, there may be more than one admin-c listed.
+
+An administrative contact(admin-c) must be someone who is physically
+located at the site of the network.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional value to be added notify array,
+        always return the current notify array.
+
+The email address to which notifications of changes 
+to the object should be sent.
+
+=head2 B<mnt_lower( [$mnt_lower] )>
+
+Accessor to the mnt_lower attribute.
+Accepts an optional mnt_lower value to be added to the mnt_lower array,
+always return the current mnt_lower array.
+
+The identifier of a registered 'mntner' object used to authorize the creation
+of 'aut-num' objects within the range specified by the as-block.
+
+If no 'mnt-lower' is specified, the 'mnt-by' attribute is used for
+authorization.
+
+=head2 B<mnt_by( [$mnt_by] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+always return the current mnt_by array.
+
+Lists a registered 'mntner' used to authorize and authenticate changes to this
+object.
+
+When your database details are protected by a 'mntner' object, then
+only persons with access to the security information of that 'mntner'
+object will be able to change details.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+The email address of who last updated the database object and the date it
+occurred.
+
+Every time a change is made to a database object, this attribute will show
+the email address of the person who made those changes.
+Please use the address format specified in RFC 822 - Standard for
+the Format of ARPA Internet Text Message and provide the date
+format using one of the following two formats: YYYYMMDD or YYMMDD.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+The database where the object is registered.
+
+=head2 B<org( [$org] )>
+
+Accessor to the org attribute.
+Accepts an optional org, always return the current org.
+
+The organisation entity this object is bound to.
+
+=cut
+
+1;
@@ -0,0 +1,206 @@
+package Net::Whois::Object::AsSet::AFRINIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -t as-block -h whois.afrinic.net
+# % This is the AfriNIC Whois server.
+# 
+# as-block:       [mandatory]  [single]     [primary/look-up key]
+# descr:          [optional]   [multiple]   [ ]
+# remarks:        [optional]   [multiple]   [ ]
+# org:            [optional]   [multiple]   [inverse key]
+# admin-c:        [mandatory]  [multiple]   [inverse key]
+# tech-c:         [mandatory]  [multiple]   [inverse key]
+# notify:         [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [multiple]   [inverse key]
+# mnt-lower:      [optional]   [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+
+__PACKAGE__->attributes( 'primary', ['as_set'] );
+__PACKAGE__->attributes( 'mandatory', [ 'as_set', 'admin_c', 'tech_c', 'mnt_by', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional', [ 'descr', 'remarks', 'org', 'notify', 'mnt_lower' ] );
+__PACKAGE__->attributes( 'single', [ 'as_set', 'source' ] );
+__PACKAGE__->attributes( 'multiple', [ 'descr', 'remarks', 'org', 'admin_c', 'tech_c', 'notify', 'mnt_by', 'mnt_lower', 'changed' ] );
+
+=head1 NAME
+
+Net::Whois::Object::AsSet::AFRINIC - an object representation of a RPSL AsSet block
+
+=head1 DESCRIPTION
+
+An as-set object defines a set of aut-num objects. 
+It defines a group of Autonomous Systems with the same routing policies.
+
+=head1 METHODS
+
+=head2 new ( @options )
+
+Constructor for the Net::Whois::Object::AsSet::AFRINIC class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+    return $self;
+}
+
+=head2 B<as_set( [$as_set])>
+
+Accessor to the as_set attribute.
+Accepts an optional as_set, always return the current as_set value.
+
+The as_set attribute defines the name of the set. It is an RPSL name that
+starts with "as-" or as_set names and AS numbers separated by colon (':').
+The later form is called Hierarchical form, the former non-hierarchical.
+There must be at least one set-name within the hierarchical form that starts 
+with 'as-'.
+
+
+=head2 B<descr( [$descr] )>
+
+Accessor to the descr attribute.
+Accepts an optional descr to be added to the descr array, 
+always return the current descr array.
+
+A short description related to the object's purpose.
+
+=head2 B<members( [$member] )>
+
+Accessor to the members attribute.
+Accepts an optional member to be added to the members array,
+always return the current 'members' array.
+
+The members attribute lists the members of the set. It can be either a list
+of AS Numbers, or other as-set names.
+
+=head2 B<mbrs_by_ref( [$mbr] )>
+
+Accessor to the mbrs_by_ref attribute.
+Accepts an optional mbr to be added to the mbrs_by_ref array,
+always return the current mbrs_by_ref array.
+
+The identifier of a registered 'mntner' object that can be used to add members
+to the as-set indirectly.
+
+The mbrs_by_ref attribute can be used in all "set" objects; it allows
+indirect population of a set. If this attribute is used, the set also includes
+objects of the corresponding type (aut-num objects for as-set, for example)
+that are protected by one of these maintainers and whose "member-of:"
+attributes refer to the name of the set. If the value of a mbrs_by_ref
+attribute is ANY, any object of the corresponding type referring to the set is
+a member of the set. If the mbrs_by_ref attribute is missing, the set is
+defined explicitly by the members attribute.
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be added to the remarks array,
+always return the current remarks array.
+
+Information about the object that cannot be stated in other attributes.
+May include a URL or email address.
+
+=head2 B<org( [$org] )>
+
+Accessor to the org attribute.
+Accepts an optional org, always return the current org.
+
+Points to an existing organisation object representing the entity that
+holds the resource.
+
+The 'ORG-' string followed by 2 to 4 characters, followed by up to 5 digits
+followed by a source specification.  The first digit must not be "0".
+Source specification starts with "-" followed by source name up to
+9-character length.
+
+=head2 B<tech_c( [$tech_c] )>
+
+Accessor to the tech_c attribute.
+Accepts an optional tech_c to be added to the tech_c array,
+always return the current tech_c array.
+
+The NIC-handle of a technical contact 'person' or 'role' object.  As more than
+one person often fulfills a role function, there may be more than one tech-c
+listed.
+
+A technical contact (tech-c) must be a person responsible for the
+day-to-day operation of the network, but does not need to be
+physically located at the site of the network.
+
+=head2 B<admin_c( [$admin_c] )>
+
+Accessor to the admin_c attribute.
+Accepts an optional admin_c to be added to the admin_c array,
+always return the current admin_c array.
+
+The NIC-handle of an on-site contact 'person' object. As more than one person
+often fulfills a role function, there may be more than one admin-c listed.
+
+An administrative contact (admin-c) must be someone who is physically
+located at the site of the network.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+The email address to which notifications of changes to this object will be
+sent.
+
+=head2 B<mnt_by( [$mnt] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt to be added to the mnt_by array,
+always return the current mnt_by array.
+
+Lists a registered 'mntner' used to authorize and authenticate changes to this
+object.
+
+When your database details are protected by a 'mntner' object, then
+only persons with access to the security information of that 'mntner'
+object will be able to change details.
+
+=head2 B<mnt_lower( [$mnt] )>
+
+Accessor to the mnt_lower attribute.
+Accepts an optional mnt to be added to the mnt_lower array,
+always return the current mnt_lower array.
+
+Specifies the identifier of a registered mntner object used
+for hierarchical authorisation.  Protects creation of objects
+directly (one level) below in the hierarchy of an object type.
+The authentication method of this maintainer object will then
+be used upon creation of any object directly below the object
+that contains the "mnt-lower:" attribute.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+The email address of who last updated the database object and the date it
+occurred.
+
+Every time a change is made to a database object, this attribute will show
+the email address of the person who made those changes.
+Please use the address format specified in RFC 822 - Standard for
+the Format of ARPA Internet Text Message and provide the date
+format using one of the following two formats: YYYYMMDD or YYMMDD.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+The database where the object is registered.
+
+=cut
+
+1;
@@ -0,0 +1,212 @@
+package Net::Whois::Object::AsSet::APNIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -h whois.apnic.net -t as-set
+# % [whois.apnic.net]
+# % Whois data copyright terms    http://www.apnic.net/db/dbcopyright.html
+# 
+# as-set:         [mandatory]  [single]     [primary/lookup key]
+# descr:          [mandatory]  [multiple]   [ ]
+# country:        [optional]   [single]     [ ]
+# members:        [optional]   [multiple]   [ ]
+# mbrs-by-ref:    [optional]   [multiple]   [inverse key]
+# remarks:        [optional]   [multiple]   [ ]
+# org:            [optional]   [multiple]   [inverse key]
+# tech-c:         [mandatory]  [multiple]   [inverse key]
+# admin-c:        [mandatory]  [multiple]   [inverse key]
+# notify:         [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [multiple]   [inverse key]
+# mnt-lower:      [optional]   [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+# 
+# % This query was served by the APNIC Whois Service version 1.68.5 (WHOIS2)
+
+__PACKAGE__->attributes( 'primary', ['as_set'] );
+__PACKAGE__->attributes( 'mandatory', [ 'as_set', 'descr', 'tech_c', 'admin_c', 'mnt_by', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional', [ 'country', 'members', 'mbrs_by_ref', 'remarks', 'org', 'notify', 'mnt_lower' ] );
+__PACKAGE__->attributes( 'single', [ 'as_set', 'country', 'source' ] );
+__PACKAGE__->attributes( 'multiple', [ 'descr', 'members', 'mbrs_by_ref', 'remarks', 'org', 'tech_c', 'admin_c', 'notify', 'mnt_by', 'mnt_lower', 'changed' ] );
+
+=head1 NAME
+
+Net::Whois::Object::AsSet::APNIC - an object representation of a RPSL AsSet block
+
+=head1 DESCRIPTION
+
+An as-set object defines a set of aut-num objects. 
+It defines a group of Autonomous Systems with the same routing policies.
+
+=head1 METHODS
+
+=head2 new ( @options )
+
+Constructor for the Net::Whois::Object::AsSet::APNIC class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+    return $self;
+}
+
+=head2 B<as_set( [$as_set])>
+
+Accessor to the as_set attribute.
+Accepts an optional as_set, always return the current as_set value.
+
+The as_set attribute defines the name of the set. It is an RPSL name that
+starts with "as-" or as_set names and AS numbers separated by colon (':').
+The later form is called Hierarchical form, the former non-hierarchical.
+There must be at least one set-name within the hierarchical form that starts 
+with 'as-'.
+
+
+=head2 B<descr( [$descr] )>
+
+Accessor to the descr attribute.
+Accepts an optional descr to be added to the descr array, 
+always return the current descr array.
+
+A short description related to the object's purpose.
+
+=head2 B<members( [$member] )>
+
+Accessor to the members attribute.
+Accepts an optional member to be added to the members array,
+always return the current 'members' array.
+
+The members attribute lists the members of the set. It can be either a list
+of AS Numbers, or other as-set names.
+
+=head2 B<mbrs_by_ref( [$mbr] )>
+
+Accessor to the mbrs_by_ref attribute.
+Accepts an optional mbr to be added to the mbrs_by_ref array,
+always return the current mbrs_by_ref array.
+
+The identifier of a registered 'mntner' object that can be used to add members
+to the as-set indirectly.
+
+The mbrs_by_ref attribute can be used in all "set" objects; it allows
+indirect population of a set. If this attribute is used, the set also includes
+objects of the corresponding type (aut-num objects for as-set, for example)
+that are protected by one of these maintainers and whose "member-of:"
+attributes refer to the name of the set. If the value of a mbrs_by_ref
+attribute is ANY, any object of the corresponding type referring to the set is
+a member of the set. If the mbrs_by_ref attribute is missing, the set is
+defined explicitly by the members attribute.
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be added to the remarks array,
+always return the current remarks array.
+
+Information about the object that cannot be stated in other attributes.
+May include a URL or email address.
+
+=head2 B<org( [$org] )>
+
+Accessor to the org attribute.
+Accepts an optional org, always return the current org.
+
+Points to an existing organisation object representing the entity that
+holds the resource.
+
+The 'ORG-' string followed by 2 to 4 characters, followed by up to 5 digits
+followed by a source specification.  The first digit must not be "0".
+Source specification starts with "-" followed by source name up to
+9-character length.
+
+=head2 B<tech_c( [$tech_c] )>
+
+Accessor to the tech_c attribute.
+Accepts an optional tech_c to be added to the tech_c array,
+always return the current tech_c array.
+
+The NIC-handle of a technical contact 'person' or 'role' object.  As more than
+one person often fulfills a role function, there may be more than one tech-c
+listed.
+
+A technical contact (tech-c) must be a person responsible for the
+day-to-day operation of the network, but does not need to be
+physically located at the site of the network.
+
+=head2 B<admin_c( [$admin_c] )>
+
+Accessor to the admin_c attribute.
+Accepts an optional admin_c to be added to the admin_c array,
+always return the current admin_c array.
+
+The NIC-handle of an on-site contact 'person' object. As more than one person
+often fulfills a role function, there may be more than one admin-c listed.
+
+An administrative contact (admin-c) must be someone who is physically
+located at the site of the network.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+The email address to which notifications of changes to this object will be
+sent.
+
+=head2 B<mnt_by( [$mnt] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt to be added to the mnt_by array,
+always return the current mnt_by array.
+
+Lists a registered 'mntner' used to authorize and authenticate changes to this
+object.
+
+When your database details are protected by a 'mntner' object, then
+only persons with access to the security information of that 'mntner'
+object will be able to change details.
+
+=head2 B<mnt_lower( [$mnt] )>
+
+Accessor to the mnt_lower attribute.
+Accepts an optional mnt to be added to the mnt_lower array,
+always return the current mnt_lower array.
+
+Specifies the identifier of a registered mntner object used
+for hierarchical authorisation.  Protects creation of objects
+directly (one level) below in the hierarchy of an object type.
+The authentication method of this maintainer object will then
+be used upon creation of any object directly below the object
+that contains the "mnt-lower:" attribute.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+The email address of who last updated the database object and the date it
+occurred.
+
+Every time a change is made to a database object, this attribute will show
+the email address of the person who made those changes.
+Please use the address format specified in RFC 822 - Standard for
+the Format of ARPA Internet Text Message and provide the date
+format using one of the following two formats: YYYYMMDD or YYMMDD.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+The database where the object is registered.
+
+=cut
+
+1;
@@ -2,7 +2,7 @@ package Net::Whois::Object::AsSet;
 
 use base qw/Net::Whois::Object/;
 
-# From : whois -t as-set  
+# From: whois -t as-set  
 #
 # % This is the RIPE Database query service.
 # % The objects are in RPSL format.
@@ -0,0 +1,259 @@
+package Net::Whois::Object::AutNum::AFRINIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -t aut-num -h whois.afrinic.net
+# % This is the AfriNIC Whois server.
+# 
+# aut-num:        [mandatory]  [single]     [primary/look-up key]
+# as-name:        [mandatory]  [single]     [ ]
+# descr:          [mandatory]  [multiple]   [ ]
+# member-of:      [optional]   [multiple]   [ ]
+# import:         [optional]   [multiple]   [ ]
+# mp-import:      [optional]   [multiple]   [ ]
+# export:         [optional]   [multiple]   [ ]
+# mp-export:      [optional]   [multiple]   [ ]
+# default:        [optional]   [multiple]   [ ]
+# mp-default:     [optional]   [multiple]   [ ]
+# remarks:        [optional]   [multiple]   [ ]
+# org:            [optional]   [single]     [inverse key]
+# admin-c:        [mandatory]  [multiple]   [inverse key]
+# tech-c:         [mandatory]  [multiple]   [inverse key]
+# notify:         [optional]   [multiple]   [inverse key]
+# mnt-lower:      [optional]   [multiple]   [inverse key]
+# mnt-routes:     [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [multiple]   [inverse key]
+# mnt-irt:        [optional]   [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+
+
+__PACKAGE__->attributes( 'primary',   ['aut_num'] );
+__PACKAGE__->attributes( 'mandatory', [ 'aut_num', 'as_name', 'descr', 'admin_c', 'tech_c', 'mnt_by', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional', [ 'member_of', 'import', 'mp_import', 'export', 'mp_export', 'default', 'mp_default', 'remarks', 'org', 'notify', 'mnt_lower', 'mnt_routes', 'mnt_irt'  ] );
+__PACKAGE__->attributes( 'single', [ 'aut_num', 'as_name', 'org', 'source' ] );
+__PACKAGE__->attributes( 'multiple', [ 'descr', 'member_of', 'import', 'mp_import', 'export', 'mp_export', 'default', 'mp_default', 'remarks', 'admin_c', 'tech_c', 'notify', 'mnt_lower', 'mnt_routes', 'mnt_by', 'mnt_irt', 'changed' ] );
+
+
+=head1 NAME
+
+Net::Whois::Object::AutNum::AFRINIC - an object representation of a RPSL AutNum block
+
+=head1 DESCRIPTION
+
+Autonomous System numbers ('aut-num' objects) are globally unique identifiers
+for Autonomous Systems.
+
+The aut-num object specifies routing policies. It refers to a group of IP
+networks that have a single and clearly defined external routing policy,
+operated by one or more network operators – an Autonomous System (AS).
+
+=head1 METHODS
+
+=head2 new ( @options )
+
+Constructor for the Net::Whois::Object::AutNum::AFRINIC class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+    return $self;
+}
+
+=head2 B<aut_num( [$aut_num] )>
+
+Accessor to the aut_num attribute.
+Accepts an optional aut_num, always return the current aut_num array.
+
+The value of the aut_num attribute is the AS Number of the Autonomous
+System that this object describes and takes the form of ASn where n is 
+a 32 bit number..
+
+Leading zeroes (AS0352) are not allowed and will be removed (AS352) by the
+database software.
+
+=cut
+
+sub aut_num {
+    my ( $self, $aut_num ) = @_;
+
+    if ( $aut_num and $aut_num !~ /^AS\d+/ ) {
+        warn "Illegal aut-num ($aut_num) : should be ASn, n being a 32 bit number with no leading 0";
+    }
+
+    return $self->_single_attribute_setget( 'aut_num', $aut_num );
+}
+
+=head2 B<as_name( [$as_name] )>
+
+Accessor to the as_name attribute.
+Accepts an optional as_name, always return the current as_name array.
+
+The as-name attribute is a symbolic name of the AS.
+
+=head2 B<descr( [$descr] )>
+
+Accessor to the descr attribute.
+Accepts an optional descr value to be added to the descr array, always return the current descr array.
+
+=head2 B<member_of( [$mbr_of] )>
+
+Accessor to the member_of attribute.
+Accepts an optional member_of value to be added to the member_of array,
+always return the current member_of array.
+
+The member_of attribute value identifies a set object that this object
+wants to be a member of. This claim, however, should be acknowledged by a
+respective mbrs_by_ref attribute in the referenced object.
+
+An aut-num may be useful to include in an 'as-set' if your network maintains a
+number of Autonomous Systems or wishes to include its routes in an upstream
+provider's routing information.
+
+To be included in an 'as-set', the 'as-set' object must:
+include the keyword "ANY" or the AS number's mbrs_by_ref attribute
+and/or list the AS number in the members attribute
+
+=head2 B<import( [$import] )>
+
+Accessor to the import attribute.
+Accepts an optional import line to be added to the import array,
+always return the current import array.
+
+The inbound IPv4 routing policy of the AS.
+
+=head2 B<mp_import( [$import] )>
+
+Accessor to the mp_import attribute.
+Accepts an optional mp_import line to be added to the import array,
+always return the current mp_import array.
+
+The inbound IPv6 routing policy of the AS.
+
+=head2 B<export( [$export] )>
+
+Accessor to the export attribute.
+Accepts an optional export line to be added to the export array,
+always return the current export array.
+
+The outbound routing policy of the AS.
+
+=head2 B<mp_export( [$mp_export] )>
+
+Accessor to the mp_export attribute.
+Accepts an optional mp_export line to be added to the mp_export array,
+always return the current mp_export array.
+
+The outbound IPv6 routing policy of the AS.
+
+=head2 B<default( [$default] )>
+
+Accessor to the default attribute.
+Accepts an optional default value to be added to the default array,
+always return the current default array.
+
+The peer network the AS will use for as a default, that is, when the AS has no
+more-specific information on where to send the traffic.
+
+=head2 B<mp_default( [$mp_default] )>
+
+Accessor to the mp_default attribute.
+Accepts an optional mp_default line to be added to the mp_default array,
+always return the current mp_default array.
+
+This attribute performs the same function as the 'default' attribute above.
+The difference is that mp-default allows both IPv4 and IPv6 addresses to be
+specified.
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be added to the remarks array,
+always return the current remarks array.
+
+Information about the object that cannot be stated in other attributes. May
+include a URL or email address.
+
+=cut
+
+=head2 B<admin_c( [$contact] )>
+
+Accessor to the admin_c attribute.
+Accepts an optional contact to be added to the admin_c array,
+always return the current admin_c array.
+
+The NIC-handle of an on-site contact 'person' object. As more than one person
+often fulfills a role function, there may be more than one admin_c listed.
+
+An administrative contact (admin_c) must be someone who is physically
+located at the site of the network.
+
+=head2 B<tech_c( [$contact] )>
+
+Accessor to the tech_c attribute.
+Accepts an optional contact to be added to the tech_c array,
+always return the current tech_c array.
+
+The NIC-handle of a technical contact 'person' or 'role' object.  As more than
+one person often fulfills a role function, there may be more than one tech_c
+listed.
+
+A technical contact (tech_c) must be a person responsible for the
+day-to-day operation of the network, but does not need to be
+physically located at the site of the network.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+=cut
+
+=head2 B<mnt_lower( [$mnt_lower] )>
+
+Accessor to the mnt_lower attribute.
+Accepts an optional mnt_lower value to be added to the mnt_lower array,
+always return the current mnt_lower array.
+
+=head2 B<mnt_routes( [$mnt_routes] )>
+
+Accessor to the mnt_routes attribute.
+Accepts an optional mnt_routes value to be added to the mnt_routes array,
+always return the current mnt_routes array.
+
+=head2 B<mnt_by( [$mnt_by] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+always return the current mnt_by array.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+The database where the object is registered.
+
+=head2 B<org( [$org] )>
+
+Accessor to the org attribute.
+Accepts an optional org, always return the current org.
+
+Only a single value for the org attribute is allowed in the aut-num object.
+This is to ensure only one organisation is responsible for this resource.
+
+=cut
+
+1;
@@ -0,0 +1,263 @@
+package Net::Whois::Object::AutNum::APNIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -h whois.apnic.net -t aut-num
+# % [whois.apnic.net]
+# % Whois data copyright terms    http://www.apnic.net/db/dbcopyright.html
+# 
+# aut-num:        [mandatory]  [single]     [primary/lookup key]
+# as-name:        [mandatory]  [single]     [ ]
+# descr:          [mandatory]  [multiple]   [ ]
+# country:        [mandatory]  [single]     [ ]
+# member-of:      [optional]   [multiple]   [inverse key]
+# import:         [optional]   [multiple]   [ ]
+# mp-import:      [optional]   [multiple]   [ ]
+# export:         [optional]   [multiple]   [ ]
+# mp-export:      [optional]   [multiple]   [ ]
+# default:        [optional]   [multiple]   [ ]
+# mp-default:     [optional]   [multiple]   [ ]
+# remarks:        [optional]   [multiple]   [ ]
+# org:            [optional]   [single]     [inverse key]
+# admin-c:        [mandatory]  [multiple]   [inverse key]
+# tech-c:         [mandatory]  [multiple]   [inverse key]
+# notify:         [optional]   [multiple]   [inverse key]
+# mnt-lower:      [optional]   [multiple]   [inverse key]
+# mnt-routes:     [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [multiple]   [inverse key]
+# mnt-irt:        [mandatory]  [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+# 
+# % This query was served by the APNIC Whois Service version 1.68.5 (WHOIS4)
+
+
+__PACKAGE__->attributes( 'primary',   ['aut_num'] );
+__PACKAGE__->attributes( 'mandatory', [ 'aut_num', 'as_name', 'descr', 'country', 'admin_c', 'tech_c', 'mnt_by', 'mnt_irt', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional', [ 'member_of', 'import', 'mp_import', 'export', 'mp_export', 'default', 'mp_default', 'remarks', 'org', 'notify', 'mnt_lower', 'mnt_routes'  ] );
+__PACKAGE__->attributes( 'single', [ 'aut_num', 'as_name', 'country', 'org', 'source' ] );
+__PACKAGE__->attributes( 'multiple', [ 'descr', 'member_of', 'import', 'mp_import', 'export', 'mp_export', 'default', 'mp_default', 'remarks', 'admin_c', 'tech_c', 'notify', 'mnt_lower', 'mnt_routes', 'mnt_by', 'mnt_irt', 'changed' ] );
+
+
+=head1 NAME
+
+Net::Whois::Object::AutNum::APNIC - an object representation of a RPSL AutNum block
+
+=head1 DESCRIPTION
+
+Autonomous System numbers ('aut-num' objects) are globally unique identifiers
+for Autonomous Systems.
+
+The aut-num object specifies routing policies. It refers to a group of IP
+networks that have a single and clearly defined external routing policy,
+operated by one or more network operators – an Autonomous System (AS).
+
+=head1 METHODS
+
+=head2 new ( @options )
+
+Constructor for the Net::Whois::Object::AutNum::APNIC class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+    return $self;
+}
+
+=head2 B<aut_num( [$aut_num] )>
+
+Accessor to the aut_num attribute.
+Accepts an optional aut_num, always return the current aut_num array.
+
+The value of the aut_num attribute is the AS Number of the Autonomous
+System that this object describes and takes the form of ASn where n is 
+a 32 bit number..
+
+Leading zeroes (AS0352) are not allowed and will be removed (AS352) by the
+database software.
+
+=cut
+
+sub aut_num {
+    my ( $self, $aut_num ) = @_;
+
+    if ( $aut_num and $aut_num !~ /^AS\d+/ ) {
+        warn "Illegal aut-num ($aut_num) : should be ASn, n being a 32 bit number with no leading 0";
+    }
+
+    return $self->_single_attribute_setget( 'aut_num', $aut_num );
+}
+
+=head2 B<as_name( [$as_name] )>
+
+Accessor to the as_name attribute.
+Accepts an optional as_name, always return the current as_name array.
+
+The as-name attribute is a symbolic name of the AS.
+
+=head2 B<descr( [$descr] )>
+
+Accessor to the descr attribute.
+Accepts an optional descr value to be added to the descr array, always return the current descr array.
+
+=head2 B<member_of( [$mbr_of] )>
+
+Accessor to the member_of attribute.
+Accepts an optional member_of value to be added to the member_of array,
+always return the current member_of array.
+
+The member_of attribute value identifies a set object that this object
+wants to be a member of. This claim, however, should be acknowledged by a
+respective mbrs_by_ref attribute in the referenced object.
+
+An aut-num may be useful to include in an 'as-set' if your network maintains a
+number of Autonomous Systems or wishes to include its routes in an upstream
+provider's routing information.
+
+To be included in an 'as-set', the 'as-set' object must:
+include the keyword "ANY" or the AS number's mbrs_by_ref attribute
+and/or list the AS number in the members attribute
+
+=head2 B<import( [$import] )>
+
+Accessor to the import attribute.
+Accepts an optional import line to be added to the import array,
+always return the current import array.
+
+The inbound IPv4 routing policy of the AS.
+
+=head2 B<mp_import( [$import] )>
+
+Accessor to the mp_import attribute.
+Accepts an optional mp_import line to be added to the import array,
+always return the current mp_import array.
+
+The inbound IPv6 routing policy of the AS.
+
+=head2 B<export( [$export] )>
+
+Accessor to the export attribute.
+Accepts an optional export line to be added to the export array,
+always return the current export array.
+
+The outbound routing policy of the AS.
+
+=head2 B<mp_export( [$mp_export] )>
+
+Accessor to the mp_export attribute.
+Accepts an optional mp_export line to be added to the mp_export array,
+always return the current mp_export array.
+
+The outbound IPv6 routing policy of the AS.
+
+=head2 B<default( [$default] )>
+
+Accessor to the default attribute.
+Accepts an optional default value to be added to the default array,
+always return the current default array.
+
+The peer network the AS will use for as a default, that is, when the AS has no
+more-specific information on where to send the traffic.
+
+=head2 B<mp_default( [$mp_default] )>
+
+Accessor to the mp_default attribute.
+Accepts an optional mp_default line to be added to the mp_default array,
+always return the current mp_default array.
+
+This attribute performs the same function as the 'default' attribute above.
+The difference is that mp-default allows both IPv4 and IPv6 addresses to be
+specified.
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be added to the remarks array,
+always return the current remarks array.
+
+Information about the object that cannot be stated in other attributes. May
+include a URL or email address.
+
+=cut
+
+=head2 B<admin_c( [$contact] )>
+
+Accessor to the admin_c attribute.
+Accepts an optional contact to be added to the admin_c array,
+always return the current admin_c array.
+
+The NIC-handle of an on-site contact 'person' object. As more than one person
+often fulfills a role function, there may be more than one admin_c listed.
+
+An administrative contact (admin_c) must be someone who is physically
+located at the site of the network.
+
+=head2 B<tech_c( [$contact] )>
+
+Accessor to the tech_c attribute.
+Accepts an optional contact to be added to the tech_c array,
+always return the current tech_c array.
+
+The NIC-handle of a technical contact 'person' or 'role' object.  As more than
+one person often fulfills a role function, there may be more than one tech_c
+listed.
+
+A technical contact (tech_c) must be a person responsible for the
+day-to-day operation of the network, but does not need to be
+physically located at the site of the network.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+=cut
+
+=head2 B<mnt_lower( [$mnt_lower] )>
+
+Accessor to the mnt_lower attribute.
+Accepts an optional mnt_lower value to be added to the mnt_lower array,
+always return the current mnt_lower array.
+
+=head2 B<mnt_routes( [$mnt_routes] )>
+
+Accessor to the mnt_routes attribute.
+Accepts an optional mnt_routes value to be added to the mnt_routes array,
+always return the current mnt_routes array.
+
+=head2 B<mnt_by( [$mnt_by] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+always return the current mnt_by array.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+The database where the object is registered.
+
+=head2 B<org( [$org] )>
+
+Accessor to the org attribute.
+Accepts an optional org, always return the current org.
+
+Only a single value for the org attribute is allowed in the aut-num object.
+This is to ensure only one organisation is responsible for this resource.
+
+=cut
+
+1;
@@ -2,7 +2,8 @@ package Net::Whois::Object::AutNum;
 
 use base qw/Net::Whois::Object/;
 
-# from : whois -t aut-num
+#  whois -t aut-num
+#
 # % This is the RIPE Database query service.
 # % The objects are in RPSL format.
 # %
@@ -13,16 +14,20 @@ use base qw/Net::Whois::Object/;
 # as-name:        [mandatory]  [single]     [ ]
 # descr:          [mandatory]  [multiple]   [ ]
 # member-of:      [optional]   [multiple]   [inverse key]
+# import-via:     [optional]   [multiple]   [ ]
 # import:         [optional]   [multiple]   [ ]
 # mp-import:      [optional]   [multiple]   [ ]
+# export-via:     [optional]   [multiple]   [ ]
 # export:         [optional]   [multiple]   [ ]
 # mp-export:      [optional]   [multiple]   [ ]
 # default:        [optional]   [multiple]   [ ]
 # mp-default:     [optional]   [multiple]   [ ]
 # remarks:        [optional]   [multiple]   [ ]
 # org:            [optional]   [single]     [inverse key]
+# sponsoring-org: [generated]  [single]     [ ]
 # admin-c:        [mandatory]  [multiple]   [inverse key]
 # tech-c:         [mandatory]  [multiple]   [inverse key]
+# status:         [generated]  [single]     [ ]
 # notify:         [optional]   [multiple]   [inverse key]
 # mnt-lower:      [optional]   [multiple]   [inverse key]
 # mnt-routes:     [optional]   [multiple]   [inverse key]
@@ -30,12 +35,12 @@ use base qw/Net::Whois::Object/;
 # changed:        [mandatory]  [multiple]   [ ]
 # source:         [mandatory]  [single]     [ ]
 # 
-# % This query was served by the RIPE Database Query Service version 1.38 (WHOIS1)
+# % This query was served by the RIPE Database Query Service version 1.73.1 (DBC-WHOIS1)
 
 __PACKAGE__->attributes( 'primary',   ['aut_num'] );
 __PACKAGE__->attributes( 'mandatory', [ 'aut_num', 'as_name', 'descr', 'tech_c', 'admin_c', 'mnt_by', 'changed', 'source' ] );
-__PACKAGE__->attributes( 'optional', [ 'member_of', 'import', 'mp_import', 'export', 'mp_export', 'default', 'mp_default', 'remarks', 'org', 'notify', 'mnt_lower', 'mnt_routes'  ] );
-__PACKAGE__->attributes( 'single', [ 'aut_num', 'as_name', 'org', 'source' ] );
+__PACKAGE__->attributes( 'optional', [ 'member_of', 'import', 'mp_import', 'export', 'mp_export', 'default', 'mp_default', 'remarks', 'org', 'notify', 'mnt_lower', 'mnt_routes' ] );
+__PACKAGE__->attributes( 'single', [ 'aut_num', 'as_name', 'org', 'sponsoring_org', 'status', 'source' ] );
 __PACKAGE__->attributes( 'multiple', [ 'descr', 'member_of', 'import', 'mp_import', 'export', 'mp_export', 'default', 'mp_default', 'remarks', 'admin_c', 'tech_c', 'notify', 'mnt_lower', 'mnt_routes', 'mnt_by', 'changed' ] );
 
 
@@ -0,0 +1,236 @@
+package Net::Whois::Object::Domain::AFRINIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -t domain -h whois.afrinic.net
+# % This is the AfriNIC Whois server.
+# 
+# domain:         [mandatory]  [single]     [primary/look-up key]
+# descr:          [mandatory]  [multiple]   [ ]
+# org:            [optional]   [multiple]   [inverse key]
+# admin-c:        [mandatory]  [multiple]   [inverse key]
+# tech-c:         [mandatory]  [multiple]   [inverse key]
+# zone-c:         [mandatory]  [multiple]   [inverse key]
+# nserver:        [optional]   [multiple]   [inverse key]
+# ds-rdata:       [optional]   [multiple]   [inverse key]
+# sub-dom:        [optional]   [multiple]   [inverse key]
+# dom-net:        [optional]   [multiple]   [ ]
+# remarks:        [optional]   [multiple]   [ ]
+# notify:         [optional]   [multiple]   [inverse key]
+# mnt-by:         [optional]   [multiple]   [inverse key]
+# mnt-lower:      [optional]   [multiple]   [inverse key]
+# refer:          [optional]   [single]     [ ]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+    
+__PACKAGE__->attributes( 'primary',   ['domain'] );
+__PACKAGE__->attributes( 'mandatory', [ 'domain', 'descr', 'admin_c', 'tech_c', 'zone_c', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional', [ 'org', 'nserver', 'ds_rdata', 'sub_dom', 'dom_net', 'remarks', 'notify', 'mnt_by', 'mnt_lower', 'refer' ] );
+__PACKAGE__->attributes( 'single', [ 'domain', 'refer', 'source' ] );
+__PACKAGE__->attributes( 'multiple', [ 'descr', 'org', 'admin_c', 'tech_c', 'zone_c', 'nserver', 'ds_rdata', 'sub_dom', 'dom_net', 'remarks', 'notify', 'mnt_by', 'mnt_lower', 'changed' ] );
+
+
+=head1 NAME
+
+Net::Whois::Object::Domain::AFRINIC - an object representation of a RPSL Domain block
+
+=head1 DESCRIPTION
+
+The domain object represents Top Level Domain (TLD) and other domain
+registrations.  It is also used for Reverse Delegations.  The domain
+name is written in fully qualified format, without a trailing " . "
+
+=head1 METHODS
+
+=head2 new ( @options )
+
+Constructor for the Net::Whois::Object::Domain::AFRINIC class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+    return $self;
+}
+
+=head2 B<domain( [$domain] )>
+
+Accessor to the domain attribute.
+Accepts an optional domain, always return the current domain.
+
+The domain name in fully qualified format, without a trailing dot. If a
+trailing dot is included it will be removed.
+
+=cut
+
+sub domain {
+    my ( $self, $domain ) = @_;
+
+    # Enforce the format
+    $domain =~ s/\.$// if $domain;
+
+    return $self->_single_attribute_setget( 'domain', $domain );
+}
+
+=head2 B<descr( [$descr] )>
+
+Accessor to the descr attribute.
+Accepts an optional descr line to be added to the descr array,
+always return the current descr array.
+
+The name of the organization responsible for the reverse delegation. Or can
+describe the use of the IP range described in the domain object.
+
+=head2 B<org( [$org] )>
+
+Accessor to the org attribute.
+Accepts an optional org value to be added to the org array,
+always return the current org array.
+
+The organisation responsible for this domain.
+
+=head2 B<admin_c( [$contact] )>
+
+Accessor to the admin_c attribute.
+Accepts an optional contact to be added to the admin_c array,
+always return the current admin_c array.
+
+The NIC-handle of an on-site contact 'person' object. As more than one person
+often fulfills a role function, there may be more than one admin_c listed.
+
+An administrative contact (admin_c) must be someone who is physically
+located at the site of the network.
+
+=head2 B<tech_c( [$contact] )>
+
+Accessor to the tech_c attribute.
+Accepts an optional contact to be added to the tech_c array,
+always return the current tech_c array.
+
+The NIC-handle of a technical contact 'person' or 'role' object.  As more than
+one person often fulfills a role function, there may be more than one tech_c
+listed.
+
+A technical contact (tech_c) must be a person responsible for the
+day-to-day operation of the network, but does not need to be
+physically located at the site of the network.
+
+=head2 B<zone_c( [$contact] )>
+
+Accessor to the zone_c attribute.
+Accepts an optional contact to be added to the zone_c array,
+always return the current zone_c array.
+
+The NIC-handle of a 'person' or 'role' object with authority over a zone.
+
+=head2 B<nserver( [$server] )>
+
+Accessor to the nserver attribute.
+Accepts an optional server to be added to the nserver array,
+always return the current nserver array.
+
+A list of nameservers for a domain object. A minimum of one nameserver is
+mandatory.
+
+=head2 B<ds_rdata( [$server] )>
+
+Accessor to the ds_rdata attribute.
+Accepts an optional server to be added to the ds_rdata array,
+always return the current ds_rdata array.
+
+The ds_rdata attribute holds information about a signed delegation record
+for DNSSEC (short for DNS Security Extensions)
+
+=head2 B<sub_dom( [$dom] )>
+
+Accessor to the sub_dom attribute.
+Accepts an optional dom to be added to the sub_dom array,
+always return the current sub_dom array.
+
+The sub_dom attribute specifies a list of sub-domains of a domain. Domain
+names are relative to the domain represented by the domain object that
+contains this attribute
+
+=head2 B<dom_net( [$dom_net] )>
+
+Accessor to the dom_net attribute.
+Accepts an optional dom_net value to be added to the dom_net array,
+always return the current dom_net array.
+
+The dom_net attribute contains a list of IP networks in a domain.
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be added to the remarks array,
+always return the current remarks array.
+
+General remarks. May include a URL or email address.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+The email address to which notifications of changes to this object should be
+sent.
+
+=head2 B<mnt_by( [$mnt_by] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+always return the current mnt_by array.
+
+Lists a registered 'mntner' used to authorize and authenticate changes to
+this object.
+
+=head2 B<mnt_lower( [$mnt_lower] )>
+
+Accessor to the mnt_lower attribute.
+Accepts an optional mnt_lower value to be added to the mnt_lower array,
+always return the current mnt_lower array.
+
+The identifier of a registered mntner object used to authorize the creation of
+reverse domain objects more specific than the reverse domain specified by this
+object.
+
+=head2 B<refer( [$refer] )>
+
+Accessor to the refer attribute.
+Accepts an optional refer, always return the current refer.
+
+The refer attribute is used to refer a query to another authorative
+database. See the "RIPE Database Query Reference Manual" for an
+explanation of its use. This will be redundant when forward domains are
+removed and may be deprecated.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+The email address of who last updated the database object and the date it
+occurred.
+
+Every time a change is made to a database object, this attribute will show
+the email address of the person who made those changes.
+Please use the address format specified in RFC 822 - Standard for
+the Format of ARPA Internet Text Message and provide the date
+format using one of the following two formats: YYYYMMDD or YYMMDD.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+The database where the object is registered.
+
+=cut
+
+1;
@@ -0,0 +1,238 @@
+package Net::Whois::Object::Domain::APNIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -h whois.apnic.net -t domain
+# % [whois.apnic.net]
+# % Whois data copyright terms    http://www.apnic.net/db/dbcopyright.html
+# 
+# domain:         [mandatory]  [single]     [primary/lookup key]
+# descr:          [mandatory]  [multiple]   [ ]
+# country:        [optional]   [single]     [ ]
+# org:            [optional]   [multiple]   [inverse key]
+# admin-c:        [mandatory]  [multiple]   [inverse key]
+# tech-c:         [mandatory]  [multiple]   [inverse key]
+# zone-c:         [mandatory]  [multiple]   [inverse key]
+# nserver:        [optional]   [multiple]   [inverse key]
+# ds-rdata:       [optional]   [multiple]   [inverse key]
+# remarks:        [optional]   [multiple]   [ ]
+# notify:         [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [multiple]   [inverse key]
+# mnt-lower:      [optional]   [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+# 
+# % This query was served by the APNIC Whois Service version 1.68.5 (WHOIS4)
+
+    
+__PACKAGE__->attributes( 'primary',   ['domain'] );
+__PACKAGE__->attributes( 'mandatory', [ 'domain', 'descr', 'admin_c', 'tech_c', 'zone_c', 'mnt_by', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional', [ 'country', 'org', 'nserver', 'ds_rdata', 'remarks', 'notify', 'mnt_lower' ] );
+__PACKAGE__->attributes( 'single', [ 'domain', 'country', 'source' ] );
+__PACKAGE__->attributes( 'multiple', [ 'descr', 'org', 'admin_c', 'tech_c', 'zone_c', 'nserver', 'ds_rdata', 'remarks', 'notify', 'mnt_by', 'mnt_lower', 'changed' ] );
+
+
+=head1 NAME
+
+Net::Whois::Object::Domain::APNIC - an object representation of a RPSL Domain block
+
+=head1 DESCRIPTION
+
+The domain object represents Top Level Domain (TLD) and other domain
+registrations.  It is also used for Reverse Delegations.  The domain
+name is written in fully qualified format, without a trailing " . "
+
+=head1 METHODS
+
+=head2 new ( @options )
+
+Constructor for the Net::Whois::Object::Domain::APNIC class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+    return $self;
+}
+
+=head2 B<domain( [$domain] )>
+
+Accessor to the domain attribute.
+Accepts an optional domain, always return the current domain.
+
+The domain name in fully qualified format, without a trailing dot. If a
+trailing dot is included it will be removed.
+
+=cut
+
+sub domain {
+    my ( $self, $domain ) = @_;
+
+    # Enforce the format
+    $domain =~ s/\.$// if $domain;
+
+    return $self->_single_attribute_setget( 'domain', $domain );
+}
+
+=head2 B<descr( [$descr] )>
+
+Accessor to the descr attribute.
+Accepts an optional descr line to be added to the descr array,
+always return the current descr array.
+
+The name of the organization responsible for the reverse delegation. Or can
+describe the use of the IP range described in the domain object.
+
+=head2 B<org( [$org] )>
+
+Accessor to the org attribute.
+Accepts an optional org value to be added to the org array,
+always return the current org array.
+
+The organisation responsible for this domain.
+
+=head2 B<admin_c( [$contact] )>
+
+Accessor to the admin_c attribute.
+Accepts an optional contact to be added to the admin_c array,
+always return the current admin_c array.
+
+The NIC-handle of an on-site contact 'person' object. As more than one person
+often fulfills a role function, there may be more than one admin_c listed.
+
+An administrative contact (admin_c) must be someone who is physically
+located at the site of the network.
+
+=head2 B<tech_c( [$contact] )>
+
+Accessor to the tech_c attribute.
+Accepts an optional contact to be added to the tech_c array,
+always return the current tech_c array.
+
+The NIC-handle of a technical contact 'person' or 'role' object.  As more than
+one person often fulfills a role function, there may be more than one tech_c
+listed.
+
+A technical contact (tech_c) must be a person responsible for the
+day-to-day operation of the network, but does not need to be
+physically located at the site of the network.
+
+=head2 B<zone_c( [$contact] )>
+
+Accessor to the zone_c attribute.
+Accepts an optional contact to be added to the zone_c array,
+always return the current zone_c array.
+
+The NIC-handle of a 'person' or 'role' object with authority over a zone.
+
+=head2 B<nserver( [$server] )>
+
+Accessor to the nserver attribute.
+Accepts an optional server to be added to the nserver array,
+always return the current nserver array.
+
+A list of nameservers for a domain object. A minimum of one nameserver is
+mandatory.
+
+=head2 B<ds_rdata( [$server] )>
+
+Accessor to the ds_rdata attribute.
+Accepts an optional server to be added to the ds_rdata array,
+always return the current ds_rdata array.
+
+The ds_rdata attribute holds information about a signed delegation record
+for DNSSEC (short for DNS Security Extensions)
+
+=head2 B<sub_dom( [$dom] )>
+
+Accessor to the sub_dom attribute.
+Accepts an optional dom to be added to the sub_dom array,
+always return the current sub_dom array.
+
+The sub_dom attribute specifies a list of sub-domains of a domain. Domain
+names are relative to the domain represented by the domain object that
+contains this attribute
+
+=head2 B<dom_net( [$dom_net] )>
+
+Accessor to the dom_net attribute.
+Accepts an optional dom_net value to be added to the dom_net array,
+always return the current dom_net array.
+
+The dom_net attribute contains a list of IP networks in a domain.
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be added to the remarks array,
+always return the current remarks array.
+
+General remarks. May include a URL or email address.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+The email address to which notifications of changes to this object should be
+sent.
+
+=head2 B<mnt_by( [$mnt_by] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+always return the current mnt_by array.
+
+Lists a registered 'mntner' used to authorize and authenticate changes to
+this object.
+
+=head2 B<mnt_lower( [$mnt_lower] )>
+
+Accessor to the mnt_lower attribute.
+Accepts an optional mnt_lower value to be added to the mnt_lower array,
+always return the current mnt_lower array.
+
+The identifier of a registered mntner object used to authorize the creation of
+reverse domain objects more specific than the reverse domain specified by this
+object.
+
+=head2 B<refer( [$refer] )>
+
+Accessor to the refer attribute.
+Accepts an optional refer, always return the current refer.
+
+The refer attribute is used to refer a query to another authorative
+database. See the "RIPE Database Query Reference Manual" for an
+explanation of its use. This will be redundant when forward domains are
+removed and may be deprecated.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+The email address of who last updated the database object and the date it
+occurred.
+
+Every time a change is made to a database object, this attribute will show
+the email address of the person who made those changes.
+Please use the address format specified in RFC 822 - Standard for
+the Format of ARPA Internet Text Message and provide the date
+format using one of the following two formats: YYYYMMDD or YYMMDD.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+The database where the object is registered.
+
+=cut
+
+1;
@@ -0,0 +1,211 @@
+package Net::Whois::Object::FilterSet::AFRINIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -t filter-set -h whois.afrinic.net
+# % This is the AfriNIC Whois server.
+# 
+# filter-set:     [mandatory]  [single]     [primary/look-up key]
+# descr:          [mandatory]  [multiple]   [ ]
+# filter:         [optional]   [single]     [ ]
+# mp-filter:      [optional]   [single]     [ ]
+# remarks:        [optional]   [multiple]   [ ]
+# org:            [optional]   [multiple]   [inverse key]
+# tech-c:         [mandatory]  [multiple]   [inverse key]
+# admin-c:        [mandatory]  [multiple]   [inverse key]
+# notify:         [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [multiple]   [inverse key]
+# mnt-lower:      [optional]   [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+
+__PACKAGE__->attributes( 'primary',   ['filter_set'] );
+__PACKAGE__->attributes( 'mandatory', [ 'filter_set', 'descr', 'tech_c', 'admin_c', 'mnt_by', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional', [ 'filter', 'mp_filter', 'remarks', 'org', 'notify', 'mnt_lower' ] );
+__PACKAGE__->attributes( 'single',    [ 'filter_set', 'filter', 'mp_filter', 'source' ] );
+__PACKAGE__->attributes( 'multiple',  [ 'descr', 'remarks', 'org', 'tech_c', 'admin_c', 'notify', 'mnt_by', 'mnt_lower', 'changed' ] );
+
+=head1 NAME
+
+Net::Whois::Object::FilterSet::AFRINIC - an object representation of a RPSL FilterSet block
+
+=head1 DESCRIPTION
+
+A FilterSet object defines a set of routes that match the criteria that you
+specify in your 'filter' – in other words it filters out routes that you do
+not want to see.
+
+=head1 METHODS
+
+=head2 new ( @options )
+
+Constructor for the Net::Whois::Object::FilterSet::AFRINIC class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+    return $self;
+}
+
+=head2 B<filter_set( [$filter_set] )>
+
+Accessor to the filter_set attribute.
+Accepts an optional filter_set value, always return the current filter_set value.
+
+The filter_set attribute defines the name of the filter. It is an RPSL
+name that starts with "fltr-".
+
+The name of a filter_set object can be hierarchical:
+
+A hierarchical filter_set name is a sequence of filter_set names and AS
+Numbers separated by colons. At least one component of the name must be an
+actual filter_set name (i.e. start with "fltr-"). All the set name
+components of a hierarchical filter-name have to be filter_set names.
+
+=cut
+
+sub filter_set {
+    my ( $self, $filter_set ) = @_;
+    if ( $filter_set and $filter_set !~ /^fltr-/i ) {
+        warn "Incorrect FilterSet's name ($filter_set) : Should start with 'FLTR-'";
+    }
+
+    return $self->_single_attribute_setget( 'filter_set', $filter_set );
+}
+
+=head2 B<descr( [$descr] )>
+
+Accessor to the descr attribute.
+Accepts an optional descr value to be added to the descr array,
+always return the current descr array.
+
+A short description related to the object's purpose.
+
+=head2 B<filter( [$filter] )>
+
+Accessor to the filter attribute.
+Accepts an optional filter value, always return the current filter.
+
+The filter attribute defines the policy filter of the set.
+
+A policy filter is a logical expression which, when applied to a
+set of routes, returns a subset of these routes – the ones that
+you have said you want to see.
+
+=head2 B<mp_filter( [$mp_filter] )>
+
+Accessor to the mp_filter attribute.
+Accepts an optional mp_filter value, always return the current mp_filter.
+
+Logical expression which when applied to a set of IPv4 or IPv6 routes returns
+a subset of these routes.
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be added to the remarks array,
+always return the current remarks array.
+
+General remarks. May include a URL or email address.
+
+=head2 B<tech_c( [$contact] )>
+
+Accessor to the tech_c attribute.
+Accepts an optional contact to be added to the tech_c array,
+always return the current tech_c array.
+
+The NIC-handle of a technical contact 'person' or 'role' object.  As more than
+one person often fulfills a role function, there may be more than one tech_c
+listed.
+
+A technical contact (tech_c) must be a person responsible for the
+day-to-day operation of the network, but does not need to be
+physically located at the site of the network.
+
+=head2 B<admin_c( [$contact] )>
+
+Accessor to the admin_c attribute.
+Accepts an optional contact to be added to the admin_c array,
+always return the current admin_c array.
+
+The NIC-handle of an on-site contact 'person' object. As more than one person
+often fulfills a role function, there may be more than one admin_c listed.
+
+An administrative contact (admin_c) must be someone who is physically
+located at the site of the network.
+
+=head2 B<org( [$org] )>
+
+Accessor to the org attribute.
+Accepts an optional org value to be added to the org array,
+always return the current org array.
+
+The organisation responsible for this FilterSet object.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+The email address of who last updated the database object and the date it
+occurred.
+
+Every time a change is made to a database object, this attribute will show
+the email address of the person who made those changes.
+Please use the address format specified in RFC 822 - Standard for
+the Format of ARPA Internet Text Message and provide the date
+format using one of the following two formats: YYYYMMDD or YYMMDD.
+
+=head2 B<mnt_by( [$mnt_by] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+always return the current mnt_by array.
+
+Lists a registered 'mntner' used to authorize and authenticate changes to this
+object.
+
+When the database details are protected by a Mntner object, then
+only persons with access to the security information of that Mntner
+object will be able to change details.
+
+=head2 B<mnt_lower( [$mnt_lower] )>
+
+Accessor to the mnt_lower attribute.
+Accepts an optional mnt_lower value to be added to the mnt_lower array,
+always return the current mnt_lower array.
+
+Sometimes there is a hierarchy of maintainers. In these cases, mnt_lower is
+used as well as mnt_by.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+The email address of who last updated the database object and the date it
+occurred.
+
+Every time a change is made to a database object, this attribute will show
+the email address of the person who made those changes.
+Please use the address format specified in RFC 822 - Standard for
+the Format of ARPA Internet Text Message and provide the date
+format using one of the following two formats: YYYYMMDD or YYMMDD.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+The database where the object is registered.
+
+=cut
+
+1;
@@ -0,0 +1,214 @@
+package Net::Whois::Object::FilterSet::APNIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -h whois.apnic.net -t filter-set
+# % [whois.apnic.net]
+# % Whois data copyright terms    http://www.apnic.net/db/dbcopyright.html
+# 
+# filter-set:     [mandatory]  [single]     [primary/lookup key]
+# descr:          [mandatory]  [multiple]   [ ]
+# filter:         [optional]   [single]     [ ]
+# mp-filter:      [optional]   [single]     [ ]
+# remarks:        [optional]   [multiple]   [ ]
+# org:            [optional]   [multiple]   [inverse key]
+# tech-c:         [mandatory]  [multiple]   [inverse key]
+# admin-c:        [mandatory]  [multiple]   [inverse key]
+# notify:         [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [multiple]   [inverse key]
+# mnt-lower:      [optional]   [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+# 
+# % This query was served by the APNIC Whois Service version 1.68.5 (WHOIS2)
+
+__PACKAGE__->attributes( 'primary',   [ 'filter_set' ] );
+__PACKAGE__->attributes( 'mandatory', [ 'filter_set', 'descr', 'tech_c', 'admin_c', 'mnt_by', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional',  [ 'filter', 'mp_filter', 'remarks', 'org', 'notify', 'mnt_lower' ] );
+__PACKAGE__->attributes( 'single',    [ 'filter_set', 'filter', 'mp_filter', 'source' ] );
+__PACKAGE__->attributes( 'multiple',  [ 'descr', 'remarks', 'org', 'tech_c', 'admin_c', 'notify', 'mnt_by', 'mnt_lower', 'changed' ] );
+
+=head1 NAME
+
+Net::Whois::Object::FilterSet::APNIC - an object representation of a RPSL FilterSet block
+
+=head1 DESCRIPTION
+
+A FilterSet object defines a set of routes that match the criteria that you
+specify in your 'filter' – in other words it filters out routes that you do
+not want to see.
+
+=head1 METHODS
+
+=head2 new ( @options )
+
+Constructor for the Net::Whois::Object::FilterSet::APNIC class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+    return $self;
+}
+
+=head2 B<filter_set( [$filter_set] )>
+
+Accessor to the filter_set attribute.
+Accepts an optional filter_set value, always return the current filter_set value.
+
+The filter_set attribute defines the name of the filter. It is an RPSL
+name that starts with "fltr-".
+
+The name of a filter_set object can be hierarchical:
+
+A hierarchical filter_set name is a sequence of filter_set names and AS
+Numbers separated by colons. At least one component of the name must be an
+actual filter_set name (i.e. start with "fltr-"). All the set name
+components of a hierarchical filter-name have to be filter_set names.
+
+=cut
+
+sub filter_set {
+    my ( $self, $filter_set ) = @_;
+    if ( $filter_set and $filter_set !~ /^fltr-/i ) {
+        warn "Incorrect FilterSet's name ($filter_set) : Should start with 'FLTR-'";
+    }
+
+    return $self->_single_attribute_setget( 'filter_set', $filter_set );
+}
+
+=head2 B<descr( [$descr] )>
+
+Accessor to the descr attribute.
+Accepts an optional descr value to be added to the descr array,
+always return the current descr array.
+
+A short description related to the object's purpose.
+
+=head2 B<filter( [$filter] )>
+
+Accessor to the filter attribute.
+Accepts an optional filter value, always return the current filter.
+
+The filter attribute defines the policy filter of the set.
+
+A policy filter is a logical expression which, when applied to a
+set of routes, returns a subset of these routes – the ones that
+you have said you want to see.
+
+=head2 B<mp_filter( [$mp_filter] )>
+
+Accessor to the mp_filter attribute.
+Accepts an optional mp_filter value, always return the current mp_filter.
+
+Logical expression which when applied to a set of IPv4 or IPv6 routes returns
+a subset of these routes.
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be added to the remarks array,
+always return the current remarks array.
+
+General remarks. May include a URL or email address.
+
+=head2 B<tech_c( [$contact] )>
+
+Accessor to the tech_c attribute.
+Accepts an optional contact to be added to the tech_c array,
+always return the current tech_c array.
+
+The NIC-handle of a technical contact 'person' or 'role' object.  As more than
+one person often fulfills a role function, there may be more than one tech_c
+listed.
+
+A technical contact (tech_c) must be a person responsible for the
+day-to-day operation of the network, but does not need to be
+physically located at the site of the network.
+
+=head2 B<admin_c( [$contact] )>
+
+Accessor to the admin_c attribute.
+Accepts an optional contact to be added to the admin_c array,
+always return the current admin_c array.
+
+The NIC-handle of an on-site contact 'person' object. As more than one person
+often fulfills a role function, there may be more than one admin_c listed.
+
+An administrative contact (admin_c) must be someone who is physically
+located at the site of the network.
+
+=head2 B<org( [$org] )>
+
+Accessor to the org attribute.
+Accepts an optional org value to be added to the org array,
+always return the current org array.
+
+The organisation responsible for this FilterSet object.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+The email address of who last updated the database object and the date it
+occurred.
+
+Every time a change is made to a database object, this attribute will show
+the email address of the person who made those changes.
+Please use the address format specified in RFC 822 - Standard for
+the Format of ARPA Internet Text Message and provide the date
+format using one of the following two formats: YYYYMMDD or YYMMDD.
+
+=head2 B<mnt_by( [$mnt_by] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+always return the current mnt_by array.
+
+Lists a registered 'mntner' used to authorize and authenticate changes to this
+object.
+
+When the database details are protected by a Mntner object, then
+only persons with access to the security information of that Mntner
+object will be able to change details.
+
+=head2 B<mnt_lower( [$mnt_lower] )>
+
+Accessor to the mnt_lower attribute.
+Accepts an optional mnt_lower value to be added to the mnt_lower array,
+always return the current mnt_lower array.
+
+Sometimes there is a hierarchy of maintainers. In these cases, mnt_lower is
+used as well as mnt_by.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+The email address of who last updated the database object and the date it
+occurred.
+
+Every time a change is made to a database object, this attribute will show
+the email address of the person who made those changes.
+Please use the address format specified in RFC 822 - Standard for
+the Format of ARPA Internet Text Message and provide the date
+format using one of the following two formats: YYYYMMDD or YYMMDD.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+The database where the object is registered.
+
+=cut
+
+1;
@@ -0,0 +1,263 @@
+package Net::Whois::Object::Inet6Num::AFRINIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -t inet6num -h whois.afrinic.net
+# % This is the AfriNIC Whois server.
+# 
+# inet6num:       [mandatory]  [single]     [primary/look-up key]
+# netname:        [mandatory]  [single]     [lookup key]
+# descr:          [mandatory]  [multiple]   [ ]
+# country:        [mandatory]  [multiple]   [ ]
+# org:            [optional]   [single]     [inverse key]
+# admin-c:        [mandatory]  [multiple]   [inverse key]
+# tech-c:         [mandatory]  [multiple]   [inverse key]
+# status:         [mandatory]  [single]     [ ]
+# remarks:        [optional]   [multiple]   [ ]
+# notify:         [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [multiple]   [inverse key]
+# mnt-lower:      [optional]   [multiple]   [inverse key]
+# mnt-routes:     [optional]   [multiple]   [inverse key]
+# mnt-domains:    [optional]   [multiple]   [inverse key]
+# mnt-irt:        [optional]   [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+# parent:         [generated]  [multiple]   [ ]
+
+__PACKAGE__->attributes( 'primary',   ['inet6num'] );
+__PACKAGE__->attributes( 'mandatory', [ 'inet6num', 'netname', 'descr', 'country', 'admin_c', 'tech_c', 'status', 'mnt_by', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional', ['org', 'remarks', 'notify', 'mnt_lower', 'mnt_routes', 'mnt_domains', 'mnt_irt' ] );
+__PACKAGE__->attributes( 'single', [ 'inet6num', 'netname', 'org', 'status', 'source' ] );
+__PACKAGE__->attributes( 'multiple', [ 'descr', 'country', 'admin_c', 'tech_c', 'remarks', 'notify', 'mnt_by', 'mnt_lower', 'mnt_routes', 'mnt_domains', 'mnt_irt', 'changed' ] );
+
+=head1 NAME
+
+Net::Whois::Object::Inet6Num::AFRINIC - an object representation of a RPSL Inet6Num block
+
+=head1 DESCRIPTION
+
+An inet6num object contains information on allocations and assignments
+of IPv6 address space.
+
+=head1 METHODS
+
+=head2 new ( @options )
+
+Constructor for the Net::Whois::Object::Inet6Num::AFRINIC class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+    return $self;
+}
+
+=head2 B<inet6num( [$inet6num] )>
+
+Accessor to the inet6num attribute.
+Accepts an optional inet6num value, always return the current inet6num value.
+
+The inet6num attribute specifies a range of IPv6 addresses that the
+inet6num object presents. The range may be a single address.
+
+Addresses can only be expressed in prefix notation
+
+=head2 B<netname( [$netname] )>
+
+Accessor to the netname attribute.
+Accepts an optional netname, always return the current netname.
+
+The netname attribute is the name of a range of IP address space. It is
+recommended that the same netname is used for any set of assignment ranges
+used for a common purpose.
+
+=head2 B<descr( [$descr] )>
+
+Accessor to the descr attribute.
+Accepts an optional descr to be added to the descr array,
+always return the current descr array.
+
+Description of the organization allocated or assigned the address space shown
+in the inet6num.
+
+=head2 B<country( [$country] )>
+
+Accessor to the country attribute.
+Accepts an optional country to be added to the country array,
+always return the current country array.
+
+The country attribute identifies the country. It has never been specified
+if this is the country where the addresses are used, where the issuing
+organisation is based or some transit country in between. There are no rules
+defined for this attribute. It cannot therefore be used in any reliable way to
+map IP addresses to countries.
+
+=head2 B<geoloc( [$geoloc] )>
+
+Accessor to the geoloc attribute.
+Accepts an optional geoloc, always return the current geoloc.
+
+The location coordinates for the resource
+
+Location coordinates of the resource. Can take one of the following forms:
+[-90,90][-180,180]
+
+=head2 B<language( [$language] )>
+
+Accessor to the language attribute.
+Accepts an optional language to be added to the language array,
+always return the current language array.
+
+Identifies the language.
+
+Valid two-letter ISO 639-1 language code.
+
+=head2 B<org( [$org] )>
+
+Accessor to the org attribute.
+Accepts an optional org, always return the current org.
+
+Only a single value for the org attribute is allowed in the inet6num
+object. This is to ensure only one organisation is responsible for this
+resource.
+
+=head2 B<admin_c( [$contact] )>
+
+Accessor to the admin_c attribute.
+Accepts an optional contact to be added to the admin_c array,
+always return the current admin_c array.
+
+The NIC-handle of an on-site contact 'person' object. As more than one person
+often fulfills a role function, there may be more than one admin_c listed.
+
+An administrative contact (admin_c) must be someone who is physically
+located at the site of the network.
+
+=head2 B<tech_c( [$contact] )>
+
+Accessor to the tech_c attribute.
+Accepts an optional contact to be added to the tech_c array,
+always return the current tech_c array.
+
+The NIC-handle of a technical contact 'person' or 'role' object.  As more than
+one person often fulfills a role function, there may be more than one tech_c
+listed.
+
+A technical contact (tech_c) must be a person responsible for the
+day-to-day operation of the network, but does not need to be
+
+=head2 B<status( [$status] )>
+
+Accessor to the status attribute.
+Accepts an optional status, always return the current status.
+
+The status attribute indicates where the address range represented by an
+inet6num object sits in a hierarchy and how it is used.
+
+Status can have one of these values:
+
+=over 4
+
+=item ALLOCATED-BY-RIR
+
+=item ALLOCATED-BY-LIR
+
+=item ASSIGNED
+
+=item ASSIGNED ANYCAST
+
+=item ASSIGNED PI
+
+=back
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be added to the remarks array,
+always return the current remarks array.
+
+General remarks. May include a URL or instructions on where to send abuse
+complaints.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+The email address to which notifications of changes to this object should be
+sent.
+
+=head2 B<mnt_by( [$mnt_by] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+always return the current mnt_by array.
+
+=head2 B<mnt_lower( [$mnt_lower] )>
+
+Accessor to the mnt_lower attribute.
+Accepts an optional mnt_lower value to be added to the mnt_lower array,
+always return the current mnt_lower array.
+
+Sometimes there is a hierarchy of maintainers. In these cases, mnt-lower is
+used as well as 'mnt-by.'
+
+=head2 B<mnt_routes( [$mnt_route] )>
+
+Accessor to the mnt_routes attribute.
+Accepts an optional mnt_route to be added to the mnt_routes array,
+always return the current mnt_routes array.
+
+The identifier of a registered Mntner object used to control the creation of
+Route6 objects associated with the address range specified by the Inet6num
+object.
+
+=head2 B<mnt_domains( [$mnt_route] )>
+
+Accessor to the mnt_domains attribute.
+Accepts an optional mnt_route to be added to the mnt_domains array,
+always return the current mnt_domains array.
+
+The identifier of a registered Mntner object used to control the creation of
+Domain objects associated with the address range specified by the Inet6num
+object.
+
+=head2 B<mnt_irt( [$mnt_irt] )>
+
+Accessor to the mnt_irt attribute.
+Accepts an optional mnt_irt to be added to the mnt_irt array,
+always return the current mnt_irt array.
+
+mnt_irt references an Irt object. Authorisation is required from the Irt
+object to be able to add this reference.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+The email address of who last updated the database object and the date it
+occurred.
+
+Every time a change is made to a database object, this attribute will show
+the email address of the person who made those changes.
+Please use the address format specified in RFC 822 - Standard for
+the Format of ARPA Internet Text Message and provide the date
+format using one of the following two formats: YYYYMMDD or YYMMDD.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+The database where the object is registered.
+
+=cut
+
+1;
@@ -0,0 +1,265 @@
+package Net::Whois::Object::Inet6Num::APNIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -h whois.apnic.net -t inet6num
+# % [whois.apnic.net]
+# % Whois data copyright terms    http://www.apnic.net/db/dbcopyright.html
+# 
+# inet6num:       [mandatory]  [single]     [primary/lookup key]
+# netname:        [mandatory]  [single]     [lookup key]
+# descr:          [mandatory]  [multiple]   [ ]
+# country:        [mandatory]  [multiple]   [ ]
+# geoloc:         [optional]   [single]     [ ]
+# language:       [optional]   [multiple]   [ ]
+# org:            [optional]   [single]     [inverse key]
+# admin-c:        [mandatory]  [multiple]   [inverse key]
+# tech-c:         [mandatory]  [multiple]   [inverse key]
+# status:         [mandatory]  [single]     [ ]
+# remarks:        [optional]   [multiple]   [ ]
+# notify:         [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [multiple]   [inverse key]
+# mnt-lower:      [optional]   [multiple]   [inverse key]
+# mnt-routes:     [optional]   [multiple]   [inverse key]
+# mnt-irt:        [mandatory]  [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+
+
+__PACKAGE__->attributes( 'primary',   [ 'inet6num'] );
+__PACKAGE__->attributes( 'mandatory', [ 'inet6num', 'netname', 'descr', 'country', 'admin_c', 'tech_c', 'status', 'mnt_by', 'mnt_irt', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional',  [ 'geoloc', 'language', 'org', 'remarks', 'notify', 'mnt_lower', 'mnt_routes' ] );
+__PACKAGE__->attributes( 'single',    [ 'inet6num', 'netname', 'geoloc', 'org', 'status', 'source' ] );
+__PACKAGE__->attributes( 'multiple',  [ 'descr', 'country', 'language', 'admin_c', 'tech_c', 'remarks', 'notify', 'mnt_by', 'mnt_lower', 'mnt_routes', 'mnt_irt', 'changed' ] );
+
+=head1 NAME
+
+Net::Whois::Object::Inet6Num::APNIC - an object representation of a RPSL Inet6Num block
+
+=head1 DESCRIPTION
+
+An inet6num object contains information on allocations and assignments
+of IPv6 address space.
+
+=head1 METHODS
+
+=head2 new ( @options )
+
+Constructor for the Net::Whois::Object::Inet6Num::APNIC class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+    return $self;
+}
+
+=head2 B<inet6num( [$inet6num] )>
+
+Accessor to the inet6num attribute.
+Accepts an optional inet6num value, always return the current inet6num value.
+
+The inet6num attribute specifies a range of IPv6 addresses that the
+inet6num object presents. The range may be a single address.
+
+Addresses can only be expressed in prefix notation
+
+=head2 B<netname( [$netname] )>
+
+Accessor to the netname attribute.
+Accepts an optional netname, always return the current netname.
+
+The netname attribute is the name of a range of IP address space. It is
+recommended that the same netname is used for any set of assignment ranges
+used for a common purpose.
+
+=head2 B<descr( [$descr] )>
+
+Accessor to the descr attribute.
+Accepts an optional descr to be added to the descr array,
+always return the current descr array.
+
+Description of the organization allocated or assigned the address space shown
+in the inet6num.
+
+=head2 B<country( [$country] )>
+
+Accessor to the country attribute.
+Accepts an optional country to be added to the country array,
+always return the current country array.
+
+The country attribute identifies the country. It has never been specified
+if this is the country where the addresses are used, where the issuing
+organisation is based or some transit country in between. There are no rules
+defined for this attribute. It cannot therefore be used in any reliable way to
+map IP addresses to countries.
+
+=head2 B<geoloc( [$geoloc] )>
+
+Accessor to the geoloc attribute.
+Accepts an optional geoloc, always return the current geoloc.
+
+The location coordinates for the resource
+
+Location coordinates of the resource. Can take one of the following forms:
+[-90,90][-180,180]
+
+=head2 B<language( [$language] )>
+
+Accessor to the language attribute.
+Accepts an optional language to be added to the language array,
+always return the current language array.
+
+Identifies the language.
+
+Valid two-letter ISO 639-1 language code.
+
+=head2 B<org( [$org] )>
+
+Accessor to the org attribute.
+Accepts an optional org, always return the current org.
+
+Only a single value for the org attribute is allowed in the inet6num
+object. This is to ensure only one organisation is responsible for this
+resource.
+
+=head2 B<admin_c( [$contact] )>
+
+Accessor to the admin_c attribute.
+Accepts an optional contact to be added to the admin_c array,
+always return the current admin_c array.
+
+The NIC-handle of an on-site contact 'person' object. As more than one person
+often fulfills a role function, there may be more than one admin_c listed.
+
+An administrative contact (admin_c) must be someone who is physically
+located at the site of the network.
+
+=head2 B<tech_c( [$contact] )>
+
+Accessor to the tech_c attribute.
+Accepts an optional contact to be added to the tech_c array,
+always return the current tech_c array.
+
+The NIC-handle of a technical contact 'person' or 'role' object.  As more than
+one person often fulfills a role function, there may be more than one tech_c
+listed.
+
+A technical contact (tech_c) must be a person responsible for the
+day-to-day operation of the network, but does not need to be
+
+=head2 B<status( [$status] )>
+
+Accessor to the status attribute.
+Accepts an optional status, always return the current status.
+
+The status attribute indicates where the address range represented by an
+inet6num object sits in a hierarchy and how it is used.
+
+Status can have one of these values:
+
+=over 4
+
+=item ALLOCATED-BY-RIR
+
+=item ALLOCATED-BY-LIR
+
+=item ASSIGNED
+
+=item ASSIGNED ANYCAST
+
+=item ASSIGNED PI
+
+=back
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be added to the remarks array,
+always return the current remarks array.
+
+General remarks. May include a URL or instructions on where to send abuse
+complaints.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+The email address to which notifications of changes to this object should be
+sent.
+
+=head2 B<mnt_by( [$mnt_by] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+always return the current mnt_by array.
+
+=head2 B<mnt_lower( [$mnt_lower] )>
+
+Accessor to the mnt_lower attribute.
+Accepts an optional mnt_lower value to be added to the mnt_lower array,
+always return the current mnt_lower array.
+
+Sometimes there is a hierarchy of maintainers. In these cases, mnt-lower is
+used as well as 'mnt-by.'
+
+=head2 B<mnt_routes( [$mnt_route] )>
+
+Accessor to the mnt_routes attribute.
+Accepts an optional mnt_route to be added to the mnt_routes array,
+always return the current mnt_routes array.
+
+The identifier of a registered Mntner object used to control the creation of
+Route6 objects associated with the address range specified by the Inet6num
+object.
+
+=head2 B<mnt_domains( [$mnt_route] )>
+
+Accessor to the mnt_domains attribute.
+Accepts an optional mnt_route to be added to the mnt_domains array,
+always return the current mnt_domains array.
+
+The identifier of a registered Mntner object used to control the creation of
+Domain objects associated with the address range specified by the Inet6num
+object.
+
+=head2 B<mnt_irt( [$mnt_irt] )>
+
+Accessor to the mnt_irt attribute.
+Accepts an optional mnt_irt to be added to the mnt_irt array,
+always return the current mnt_irt array.
+
+mnt_irt references an Irt object. Authorisation is required from the Irt
+object to be able to add this reference.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+The email address of who last updated the database object and the date it
+occurred.
+
+Every time a change is made to a database object, this attribute will show
+the email address of the person who made those changes.
+Please use the address format specified in RFC 822 - Standard for
+the Format of ARPA Internet Text Message and provide the date
+format using one of the following two formats: YYYYMMDD or YYMMDD.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+The database where the object is registered.
+
+=cut
+
+1;
@@ -5,7 +5,7 @@ use base qw/Net::Whois::Object/;
 # http://www.ripe.net/data-tools/support/documentation/update-ref-manual#section-12
 # http://www.apnic.net/apnic-info/whois_search/using-whois/guide/inet6num
 #
-# From : whois -t inet6num  
+# From: whois -t inet6num  
 # % This is the RIPE Database query service.
 # % The objects are in RPSL format.
 # %
@@ -39,8 +39,8 @@ use base qw/Net::Whois::Object/;
 # mnt-irt:       [mandatory]  [single]     [inverse key]
 __PACKAGE__->attributes( 'primary',   ['inet6num'] );
 __PACKAGE__->attributes( 'mandatory', [ 'inet6num', 'netname', 'status', 'source' ] );
-__PACKAGE__->attributes( 'optional', ['geoloc', 'language', 'org', 'remarks', 'notify', 'mnt_lower', 'mnt_routes', 'mnt_domains', 'mnt_irt' ] );
-__PACKAGE__->attributes( 'single', [ 'inet6num', 'netname', 'geoloc', 'org', 'status', 'source' ] );
+__PACKAGE__->attributes( 'optional', ['geoloc', 'language', 'org', 'remarks', 'notify', 'mnt_lower', 'mnt_routes', 'mnt_domains', 'mnt_irt', 'assignment_size' ] );
+__PACKAGE__->attributes( 'single', [ 'inet6num', 'netname', 'geoloc', 'org', 'status', 'source', 'assignment_size' ] );
 __PACKAGE__->attributes( 'multiple', [ 'descr', 'country','language', 'tech_c', 'admin_c', 'remarks', 'notify', 'mnt_by', 'mnt_lower', 'mnt_routes', 'mnt_domains', 'mnt_irt', 'changed' ] );
 
 =head1 NAME
@@ -0,0 +1,264 @@
+package Net::Whois::Object::InetNum::AFRINIC;
+
+use base qw/Net::Whois::Object/;
+
+#
+# whois -h whois.afrinic.net -t inetnum
+# 
+# % This is the AfriNIC Whois server.
+# 
+# inetnum:        [mandatory]  [single]     [primary/look-up key]
+# netname:        [mandatory]  [single]     [lookup key]
+# descr:          [mandatory]  [multiple]   [ ]
+# country:        [mandatory]  [multiple]   [ ]
+# org:            [optional]   [single]     [inverse key]
+# admin-c:        [mandatory]  [multiple]   [inverse key]
+# tech-c:         [mandatory]  [multiple]   [inverse key]
+# status:         [mandatory]  [single]     [ ]
+# remarks:        [optional]   [multiple]   [ ]
+# notify:         [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [multiple]   [inverse key]
+# mnt-lower:      [optional]   [multiple]   [inverse key]
+# mnt-domains:    [optional]   [multiple]   [inverse key]
+# mnt-routes:     [optional]   [multiple]   [inverse key]
+# mnt-irt:        [optional]   [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+# parent:         [generated]  [multiple]   [ ]
+
+
+__PACKAGE__->attributes( 'primary', ['inetnum'] );
+__PACKAGE__->attributes( 'mandatory', [ 'inetnum', 'netname', 'descr', 'country', 'admin_c', 'tech_c', 'status', 'mnt_by', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional', [ 'org', 'remarks', 'notify', 'mnt_lower', 'mnt_domains', 'mnt_routes', 'mnt_irt', 'parent' ] );
+__PACKAGE__->attributes( 'single', [ 'inetnum', 'netname', 'geoloc', 'org', 'status', 'source' ] );
+__PACKAGE__->attributes( 'multiple', [ 'descr', 'country', 'admin_c', 'tech_c', 'remarks', 'notify', 'mnt_by', 'mnt_lower', 'mnt_domains', 'mnt_routes', 'mnt_irt', 'changed', 'parent' ] );
+
+
+=head1 NAME
+
+Net::Whois::Object::InetNum::AFRINIC - an object representation of a RPSL InetNum block
+
+=head1 DESCRIPTION
+
+An inetnum object contains information on allocations and assignments
+of IPv4 address space.
+
+=head1 METHODS
+
+=head2 new ( @options )
+
+Constructor for the Net::Whois::Object::InetNum::AFRINIC class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+
+    $self->_init(@options);
+
+    return $self;
+}
+
+=head2 B<inetnum( [$inetnum] )>
+
+Accessor to the inetnum attribute.
+Accepts an optional inetnum value, always return the current inetnum value.
+
+=head2 B<netname( [$netname] )>
+
+Accessor to the netname attribute.
+Accepts an optional netname, always return the current netname.
+
+=head2 B<descr( [$descr] )>
+
+Accessor to the descr attribute.
+Accepts an optional descr value to be added to the descr array,
+always return the current descr array.
+
+=head2 B<country( [$country] )>
+
+Accessor to the country attribute.
+Accepts an optional country to be added to the country array,
+always return the current country array.
+
+=head2 B<geoloc( [$geoloc] )>
+
+Accessor to the geoloc attribute.
+Accepts an optional geoloc, always return the current geoloc.
+
+The location coordinates for the resource
+
+Location coordinates of the resource. Can take one of the following forms:
+[-90,90][-180,180]
+
+=head2 B<language( [$language] )>
+
+Accessor to the language attribute.
+Accepts an optional language to be added to the language array,
+always return the current language array.
+
+Identifies the language.
+
+Valid two-letter ISO 639-1 language code.
+=head2 B<org( [$org] )>
+
+Accessor to the 'org' attribute.
+Accepts an optional org, always return the current org.
+
+Only a single value for the org attribute is allowed in the Inetnum object.
+This is to ensure only one organisation is responsible for this resource.
+
+=head2 B<admin_c( [$contact] )>
+
+Accessor to the admin_c attribute.
+Accepts an optional contact to be added to the admin_c array,
+always return the current admin_c array.
+
+The NIC-handle of an on-site contact Person object. As more than one person
+often fulfills a role function, there may be more than one admin_c listed.
+
+An administrative contact (admin_c) must be someone who is physically
+located at the site of the network.
+
+=head2 B<tech_c( [$contact] )>
+
+Accessor to the tech_c attribute.
+Accepts an optional contact to be added to the tech_c array,
+always return the current tech_c array.
+
+The NIC-handle of a technical contact Person or Role object.  As more than
+one person often fulfills a role function, there may be more than one tech_c
+listed.
+
+A technical contact (tech_c) must be a person responsible for the
+day-to-day operation of the network, but does not need to be
+physically located at the site of the network.
+
+=head2 B<status( [$status] )>
+
+Accessor to the 'status' attribute.
+Accepts an optional status, always return the current status.
+
+The status attribute indicates where the address range represented by an
+inetnum object sits in a hierarchy and how it is used.
+
+Status can have one of these values:
+
+=over 4
+
+=item ALLOCATED UNSPECIFIED
+
+=item ALLOCATED PA
+
+=item ALLOCATED PI
+
+=item LIR-PARTITIONED PA
+
+=item LIR-PARTITIONED PI
+
+=item SUB-ALLOCATED PA
+
+=item ASSIGNED PA
+
+=item ASSIGNED PI
+
+=item ASSIGNED ANYCAST
+
+=item EARLY-REGISTRATION
+
+=item NOT-SET
+
+=back
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be added to the remarks array,
+always return the current remarks array.
+
+General remarks. May include a URL or instructions on where to send abuse
+complaints.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+The email address to which notifications of changes to this object should be
+sent.
+
+=head2 B<mnt_by( [$mnt_by] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+always return the current mnt_by array.
+
+Lists a registered Mntner used to authorize and authenticate changes to this
+object.
+
+=head2 B<mnt_lower( [$mnt_lower] )>
+
+Accessor to the mnt_lower attribute.
+Accepts an optional mnt_lower value to be added to the mnt_lower array,
+always return the current mnt_lower array.
+
+Sometimes there is a hierarchy of maintainers. In these cases, mnt_lower is
+used as well as mnt_by.
+
+=head2 B<mnt_routes( [$mnt_route] )>
+
+Accessor to the mnt_routes attribute.
+Accepts an optional mnt_route to be added to the mnt_routes array,
+always return the current mnt_routes array.
+
+The identifier of a registered Mntner object used to control the creation of
+Route objects associated with the address range specified by the Inetnum
+object.
+
+=head2 B<mnt_domains( [$mnt_domain] )>
+
+Accessor to the mnt_domains attribute.
+Accepts an optional mnt_domain to be added to the mnt_domains array,
+always return the current mnt_domains array.
+
+The identifier of a registered Mntner object used to control the creation of
+Domain objects associated with the address range specified by the Inetnum
+object.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+The email address of who last updated the database object and the date it
+occurred.
+
+Every time a change is made to a database object, this attribute will show
+the email address of the person who made those changes.
+Please use the address format specified in RFC 822 - Standard for
+the Format of ARPA Internet Text Message and provide the date
+format using one of the following two formats: YYYYMMDD or YYMMDD.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+The database where the object is registered.
+
+=head2 B<mnt_irt( [$mnt_irt] )>
+
+Accessor to the mnt_irt attribute.
+Accepts an optional mnt_irt value to be added to the mnt_irt array,
+always return the current mnt_irt array.
+
+The identifier of a registered Mntner object used to provide information
+about a Computer Security Incident Response Team (CSIRT).
+
+=cut
+
+1;
@@ -0,0 +1,263 @@
+package Net::Whois::Object::InetNum::APNIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -h whois.apnic.net -t inetnum
+# % [whois.apnic.net]
+# % Whois data copyright terms    http://www.apnic.net/db/dbcopyright.html
+# 
+# inetnum:        [mandatory]  [single]     [primary/lookup key]
+# netname:        [mandatory]  [single]     [lookup key]
+# descr:          [mandatory]  [multiple]   [ ]
+# country:        [mandatory]  [multiple]   [ ]
+# geoloc:         [optional]   [single]     [ ]
+# language:       [optional]   [multiple]   [ ]
+# org:            [optional]   [single]     [inverse key]
+# admin-c:        [mandatory]  [multiple]   [inverse key]
+# tech-c:         [mandatory]  [multiple]   [inverse key]
+# status:         [mandatory]  [single]     [ ]
+# remarks:        [optional]   [multiple]   [ ]
+# notify:         [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [multiple]   [inverse key]
+# mnt-lower:      [optional]   [multiple]   [inverse key]
+# mnt-routes:     [optional]   [multiple]   [inverse key]
+# mnt-irt:        [mandatory]  [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+# 
+# % This query was served by the APNIC Whois Service version 1.68.5 (WHOIS4)
+
+__PACKAGE__->attributes( 'primary',   [ 'inetnum' ] );
+__PACKAGE__->attributes( 'mandatory', [ 'inetnum', 'netname', 'descr', 'country', 'admin_c', 'tech_c', 'status', 'mnt_by', 'mnt_irt', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional',  [ 'geoloc', 'language', 'org', 'remarks', 'notify', 'mnt_lower', 'mnt_routes' ] );
+__PACKAGE__->attributes( 'single',    [ 'inetnum', 'netname', 'geoloc', 'org', 'status', 'source' ] );
+__PACKAGE__->attributes( 'multiple',  [ 'descr', 'country', 'language', 'admin_c', 'tech_c', 'remarks', 'notify', 'mnt_by', 'mnt_lower', 'mnt_routes', 'mnt_irt', 'changed' ] );
+
+=head1 NAME
+
+Net::Whois::Object::InetNum::APNIC - an object representation of a RPSL InetNum block
+
+=head1 DESCRIPTION
+
+An inetnum object contains information on allocations and assignments
+of IPv4 address space.
+
+=head1 METHODS
+
+=head2 new ( @options )
+
+Constructor for the Net::Whois::Object::InetNum::APNIC class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+
+    $self->_init(@options);
+
+    return $self;
+}
+
+=head2 B<inetnum( [$inetnum] )>
+
+Accessor to the inetnum attribute.
+Accepts an optional inetnum value, always return the current inetnum value.
+
+=head2 B<netname( [$netname] )>
+
+Accessor to the netname attribute.
+Accepts an optional netname, always return the current netname.
+
+=head2 B<descr( [$descr] )>
+
+Accessor to the descr attribute.
+Accepts an optional descr value to be added to the descr array,
+always return the current descr array.
+
+=head2 B<country( [$country] )>
+
+Accessor to the country attribute.
+Accepts an optional country to be added to the country array,
+always return the current country array.
+
+=head2 B<geoloc( [$geoloc] )>
+
+Accessor to the geoloc attribute.
+Accepts an optional geoloc, always return the current geoloc.
+
+The location coordinates for the resource
+
+Location coordinates of the resource. Can take one of the following forms:
+[-90,90][-180,180]
+
+=head2 B<language( [$language] )>
+
+Accessor to the language attribute.
+Accepts an optional language to be added to the language array,
+always return the current language array.
+
+Identifies the language.
+
+Valid two-letter ISO 639-1 language code.
+=head2 B<org( [$org] )>
+
+Accessor to the 'org' attribute.
+Accepts an optional org, always return the current org.
+
+Only a single value for the org attribute is allowed in the Inetnum object.
+This is to ensure only one organisation is responsible for this resource.
+
+=head2 B<admin_c( [$contact] )>
+
+Accessor to the admin_c attribute.
+Accepts an optional contact to be added to the admin_c array,
+always return the current admin_c array.
+
+The NIC-handle of an on-site contact Person object. As more than one person
+often fulfills a role function, there may be more than one admin_c listed.
+
+An administrative contact (admin_c) must be someone who is physically
+located at the site of the network.
+
+=head2 B<tech_c( [$contact] )>
+
+Accessor to the tech_c attribute.
+Accepts an optional contact to be added to the tech_c array,
+always return the current tech_c array.
+
+The NIC-handle of a technical contact Person or Role object.  As more than
+one person often fulfills a role function, there may be more than one tech_c
+listed.
+
+A technical contact (tech_c) must be a person responsible for the
+day-to-day operation of the network, but does not need to be
+physically located at the site of the network.
+
+=head2 B<status( [$status] )>
+
+Accessor to the 'status' attribute.
+Accepts an optional status, always return the current status.
+
+The status attribute indicates where the address range represented by an
+inetnum object sits in a hierarchy and how it is used.
+
+Status can have one of these values:
+
+=over 4
+
+=item ALLOCATED UNSPECIFIED
+
+=item ALLOCATED PA
+
+=item ALLOCATED PI
+
+=item LIR-PARTITIONED PA
+
+=item LIR-PARTITIONED PI
+
+=item SUB-ALLOCATED PA
+
+=item ASSIGNED PA
+
+=item ASSIGNED PI
+
+=item ASSIGNED ANYCAST
+
+=item EARLY-REGISTRATION
+
+=item NOT-SET
+
+=back
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be added to the remarks array,
+always return the current remarks array.
+
+General remarks. May include a URL or instructions on where to send abuse
+complaints.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+The email address to which notifications of changes to this object should be
+sent.
+
+=head2 B<mnt_by( [$mnt_by] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+always return the current mnt_by array.
+
+Lists a registered Mntner used to authorize and authenticate changes to this
+object.
+
+=head2 B<mnt_lower( [$mnt_lower] )>
+
+Accessor to the mnt_lower attribute.
+Accepts an optional mnt_lower value to be added to the mnt_lower array,
+always return the current mnt_lower array.
+
+Sometimes there is a hierarchy of maintainers. In these cases, mnt_lower is
+used as well as mnt_by.
+
+=head2 B<mnt_routes( [$mnt_route] )>
+
+Accessor to the mnt_routes attribute.
+Accepts an optional mnt_route to be added to the mnt_routes array,
+always return the current mnt_routes array.
+
+The identifier of a registered Mntner object used to control the creation of
+Route objects associated with the address range specified by the Inetnum
+object.
+
+=head2 B<mnt_domains( [$mnt_domain] )>
+
+Accessor to the mnt_domains attribute.
+Accepts an optional mnt_domain to be added to the mnt_domains array,
+always return the current mnt_domains array.
+
+The identifier of a registered Mntner object used to control the creation of
+Domain objects associated with the address range specified by the Inetnum
+object.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+The email address of who last updated the database object and the date it
+occurred.
+
+Every time a change is made to a database object, this attribute will show
+the email address of the person who made those changes.
+Please use the address format specified in RFC 822 - Standard for
+the Format of ARPA Internet Text Message and provide the date
+format using one of the following two formats: YYYYMMDD or YYMMDD.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+The database where the object is registered.
+
+=head2 B<mnt_irt( [$mnt_irt] )>
+
+Accessor to the mnt_irt attribute.
+Accepts an optional mnt_irt value to be added to the mnt_irt array,
+always return the current mnt_irt array.
+
+The identifier of a registered Mntner object used to provide information
+about a Computer Security Incident Response Team (CSIRT).
+
+=cut
+
+1;
@@ -5,7 +5,7 @@ use base qw/Net::Whois::Object/;
 # http://www.ripe.net/data-tools/support/documentation/update-ref-manual#section-13
 # http://www.apnic.net/apnic-info/whois_search/using-whois/guide/inetnum
 #
-# From :  whois -t inetnum 
+# From:  whois -t inetnum 
 # % This is the RIPE Database query service.
 # % The objects are in RPSL format.
 # %
@@ -0,0 +1,226 @@
+package Net::Whois::Object::InetRtr::AFRINIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -t inet-rtr -h whois.afrinic.net
+# % This is the AfriNIC Whois server.
+# 
+# inet-rtr:       [mandatory]  [single]     [primary/look-up key]
+# descr:          [mandatory]  [multiple]   [ ]
+# alias:          [optional]   [multiple]   [ ]
+# local-as:       [mandatory]  [single]     [inverse key]
+# ifaddr:         [mandatory]  [multiple]   [lookup key]
+# interface:      [optional]   [multiple]   [lookup key]
+# peer:           [optional]   [multiple]   [ ]
+# mp-peer:        [optional]   [multiple]   [ ]
+# member-of:      [optional]   [multiple]   [inverse key]
+# remarks:        [optional]   [multiple]   [ ]
+# org:            [optional]   [multiple]   [inverse key]
+# admin-c:        [mandatory]  [multiple]   [inverse key]
+# tech-c:         [mandatory]  [multiple]   [inverse key]
+# notify:         [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+
+__PACKAGE__->attributes( 'primary', ['inet_rtr'] );
+__PACKAGE__->attributes( 'mandatory', [ 'inet_rtr', 'descr', 'local_as', 'ifaddr', 'admin_c', 'tech_c', 'mnt_by', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional', [ 'alias', 'interface', 'peer', 'mp_peer', 'member_of', 'remarks', 'org', 'notify' ] );
+__PACKAGE__->attributes( 'single', [ 'inet_rtr', 'local_as', 'source' ] );
+__PACKAGE__->attributes( 'multiple', [ 'descr', 'alias', 'ifaddr', 'interface', 'peer', 'mp_peer', 'member_of', 'remarks', 'org', 'admin_c', 'tech_c', 'notify', 'mnt_by', 'changed' ] );
+
+
+=head1 NAME
+
+Net::Whois::Object::InetRtr::AFRINIC - an object representation of a RPSL InetRtr block
+
+=head1 DESCRIPTION
+
+The inet-rtr object specifies routers.
+
+=head1 METHODS
+
+=head2 new ( @options )
+
+Constructor for the Net::Whois::Object::InetRtr::AFRINIC class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+    return $self;
+}
+
+=head2 B<inet_rtr( [$inet_rtr] )>
+
+Accessor to the inet_rtr attribute.
+Accepts an optional inet_rtr, always return the current inet_rtr value.
+
+The inet_rtr attribute is a valid DNS name for a router without a trailing
+dot.
+
+=head2 B<descr( [$descr] )>
+
+Accessor to the descr attribute.
+Accepts an optional descr value to be added to the descr array,
+always return the current descr array.
+
+A short description related to the object's purpose.
+
+=head2 B<alias( [$alias] )>
+
+Accessor to the alias attribute.
+Accepts an optional alias to be added to the alias array,
+always return the current alias array.
+
+Each alias attribute, if present, is also standard DNS name for the
+specified router.
+
+=head2 B<local_as( [$local_as] )>
+
+Accessor to the local_as attribute.
+Accepts an optional local_as, always return the current local_as.
+
+The local_as attribute specifies the AS Number of the AS that owns or
+operates this router.
+
+=head2 B<ifaddr( [$ifaddr] )>
+
+Accessor to the ifaddr attribute.
+Accepts an optional ifaddr value to be added to the ifaddr array,
+always return the current ifaddr array.
+
+The ifaddr attribute specifies the interface address within an Internet
+router, as well as an optional action to set other parameters on this
+interface.
+
+=head2 B<peer( [$peer] )>
+
+Accessor to the peer attribute.
+Accepts an optional peer to be added to the peer array,
+always return the current peer array.
+
+The peer attribute specifies the details of any interior or exterior router
+peering.
+
+=head2 B<member_of( [$member_of] )>
+
+Accessor to the member_of attribute.
+Accepts an optional member_of value to be be added to the member_of array,
+always return the current member_of array.
+
+The member_of attribute value identifies a set object that this object
+wants to be a member of. This claim, however, should be acknowledged by a
+respective mbrs-by-ref attribute in the referenced object.
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be added to the remarks array,
+always return the current remarks array.
+
+General remarks. May include a URL or instructions on where to send abuse
+complaints.
+
+=head2 B<admin_c( [$contact] )>
+
+Accessor to the admin_c attribute.
+Accepts an optional contact to be added to the admin_c array,
+always return the current admin_c array.
+
+The NIC-handle of an on-site contact Person object. As more than one person
+often fulfills a role function, there may be more than one admin_c listed.
+
+An administrative contact (admin_c) must be someone who is physically
+located at the site of the network.
+
+=head2 B<tech_c( [$contact] )>
+
+Accessor to the tech_c attribute.
+Accepts an optional contact to be added to the tech_c array,
+always return the current tech_c array.
+
+The NIC-handle of a technical contact Person or Role object.  As more than
+one person often fulfills a role function, there may be more than one tech_c
+listed.
+
+A technical contact (tech_c) must be a person responsible for the
+day-to-day operation of the network, but does not need to be
+physically located at the site of the network.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+The email address to which notifications of changes to this object should
+be sent.
+
+=head2 B<mnt_by( [$mnt_by] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+always return the current mnt_by array.
+
+Lists a registered 'mntner' used to authorize and authenticate changes to this
+object.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+The email address of who last updated the database object and the date it
+occurred.
+
+Every time a change is made to a database object, this attribute will show
+the email address of the person who made those changes.
+Please use the address format specified in RFC 822 - Standard for
+the Format of ARPA Internet Text Message and provide the date
+format using one of the following two formats: YYYYMMDD or YYMMDD.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+The database where the object is registered.
+
+=head2 B<mp_peer( [$peer] )>
+
+Accessor to the mp_peer attribute.
+Accepts an optional peer to be added to the mp_peer array,
+always return the current mp_peer array.
+
+This attribute performs the same function as the peer attribute above. The
+difference is that mp-peer allows both IPv4 and IPv6 address families to be
+specified.
+
+The mp-peer attribute extends the peer attribute for IPv6 addresses.
+
+=head2 B<interface( [$interface] )>
+
+Accessor to the interface attribute.
+Accepts an optional interface to be added to the interface array,
+always return the current interface array.
+
+The interface attribute specifies a multi-protocol interface address within
+an Internet router, optional action and tunnel definition.
+
+=head2 B<org( [$org] )>
+
+Accessor to the org attribute.
+Accepts an optional org to be added to the org array,
+always return the current org array.
+
+The organisation entity this object is bound to.
+
+=cut
+
+1;
@@ -0,0 +1,51 @@
+package Net::Whois::Object::Information;
+
+use base qw/Net::Whois::Object/;
+
+__PACKAGE__->attributes( 'mandatory', ['comment'] );
+__PACKAGE__->attributes( 'optional', [] );
+__PACKAGE__->attributes( 'multiple',  ['comment'] );
+
+=head1 NAME
+
+Net::Whois::Object::Information - an object representation of the RPSL Information block
+
+=head1 DESCRIPTION
+
+output starting with the % sign is either a server response code or
+an informational message. A comment contains a white space after the
+% sign, while server messages start right after the % sign. Please
+see Appendix A2 "RIPE Database response codes and messages" for more
+information.
+
+* An empty line ("\n\n") is an object delimiter. 
+
+* Two empty lines mean the end of a server response. The "members:" attribute lists the members of the set.  The
+"members:" attribute is a list of AS numbers, or other as-set names.
+
+=head1 METHODS
+
+=head2 new ( @options )
+
+Constructor for the Net::Whois::Object::Information class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+    return $self;
+}
+
+=head2 B<comment( [$comment] )>
+
+Accessor to the comment attribute.
+Accepts an optional comment to be added to the comment array,
+always return the current comment array.
+
+=cut
+
+1;
@@ -0,0 +1,261 @@
+package Net::Whois::Object::Irt::AFRINIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -t irt -h whois.afrinic.net
+# % This is the AfriNIC Whois server.
+# 
+# irt:            [mandatory]  [single]     [primary/look-up key]
+# address:        [mandatory]  [multiple]   [ ]
+# phone:          [optional]   [multiple]   [ ]
+# fax-no:         [optional]   [multiple]   [ ]
+# e-mail:         [mandatory]  [multiple]   [lookup key]
+# abuse-mailbox:  [mandatory]  [multiple]   [inverse key]
+# signature:      [optional]   [multiple]   [ ]
+# encryption:     [optional]   [multiple]   [ ]
+# org:            [optional]   [multiple]   [inverse key]
+# admin-c:        [mandatory]  [multiple]   [inverse key]
+# tech-c:         [mandatory]  [multiple]   [inverse key]
+# auth:           [mandatory]  [multiple]   [inverse key]
+# remarks:        [optional]   [multiple]   [ ]
+# irt-nfy:        [optional]   [multiple]   [inverse key]
+# notify:         [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+
+__PACKAGE__->attributes( 'primary', ['irt'] );
+__PACKAGE__->attributes( 'mandatory', [ 'irt', 'address', 'e_mail', 'abuse_mailbox', 'admin_c', 'tech_c', 'auth', 'mnt_by', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional', [ 'phone', 'fax_no', 'signature', 'encryption', 'org', 'remarks', 'irt_nfy', 'notify' ] );
+__PACKAGE__->attributes( 'single', [ 'irt', 'source' ] );
+__PACKAGE__->attributes( 'multiple', [ 'address', 'phone', 'fax_no', 'e_mail', 'abuse_mailbox', 'signature', 'encryption', 'org', 'admin_c', 'tech_c', 'auth', 'remarks', 'irt_nfy', 'notify', 'mnt_by', 'changed' ] );
+
+=head1 NAME
+
+Net::Whois::Object::Irt::AFRINIC - an object representation of the RPSL Irt block
+
+=head1 DESCRIPTION
+
+The irt object is used to provide information about a Computer Security
+Incident Response Team (CSIRT).  IRTs or CSIRTs specifically respond to
+computer security incident reports and activity.
+
+They are dedicated abuse handling teams, (as distinct from network operational
+departments) which review and respond to abuse reports.
+
+=head1 METHODS
+
+=head2 B<new( %options )>
+
+Constructor for the Net::Whois::Object::Irt::AFRINIC class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+
+    return $self;
+
+}
+
+=head2 B<irt( [$irt] )>
+
+Accessor to the irt attribute.
+Accepts an optional irt, always return the current irt.
+
+The irt object name starts with "IRT-".
+
+=cut
+
+sub irt {
+    my ( $self, $irt ) = @_;
+    if ( $irt and $irt !~ /^IRT-/i ) {
+        warn "Irt name not valid ($irt) : Should start with 'IRT-'";
+    }
+    return $self->_single_attribute_setget( 'irt', $irt );
+}
+
+=head2 B<address( [$address] )>
+
+Accessor to the address attribute.
+Accepts an optional address to be added to the address array,
+always return the current address array.
+
+Full postal address of a contact.
+
+You can use any combination of alphanumeric characters.
+More than one line can be used.
+
+=cut
+
+sub address {
+    my ( $self, $address ) = @_;
+
+    return $self->_multiple_attribute_setget( 'address', $address );
+}
+
+=head2 B<phone( [$phone] )>
+
+Accessor to the phone attribute.
+Accepts an optional phone number to be added to the phone array,
+always return the current phone array.
+
+A contact telephone number.
+
++ <international code> <area code> <phone #>
+
++ <international code> <area code> <phone #> ext. <#>
+
+ EXAMPLE
+ phone: +681 368 0844 ext. 32
+
+=head2 B<fax_no( [$fax_no] )>
+
+Accessor to the fax_no attribute.
+Accepts an optional fax_no to be added to the fax_no array,
+always return the current fax_no array.
+
+A contact fax number.
+
++ <international code> <area code> <fax #>
+
+=head2 B<e_mail( [$e_mail] )>
+
+Accessor to the e_mail attribute.
+Accepts an optional e_mail to be added to the e_mail array,
+always return the current e_mail array.
+
+A contact email address for non-abuse/technical incidents.
+
+=head2 B<abuse_mailbox( [$abuse_mailbox] )>
+
+Accessor to the abuse_mailbox attribute.
+Accepts an optional abuse_mailbox to be added to the abuse_mailbox array,
+always return the current abuse_mailbox array.
+
+Specifies the email address to which abuse complaints should be sent.
+
+=head2 B<signature( [$signature] )>
+
+Accessor to the signature attribute.
+Accepts an optional signature to be added to the signature array,
+always return the current signature array.
+
+References a KeyCert object representing a CSIRT public key used by the
+team to sign their correspondence.
+
+=head2 B<encryption( [$encryption] )>
+
+Accessor to the encryption attribute.
+Accepts an optional encryption to be added to the encryption array,
+always return the current encryption array.
+
+References a KeyCert object representing a CSIRT public key used to encrypt
+correspondence sent to the CSIRT.
+
+=head2 B<org( [$org] )>
+
+Accessor to the org attribute.
+Accepts an optional org value to be added to the org array,
+always return the current org array.
+
+The organisation responsible for this resource.
+
+=head2 B<auth( [$auth] )>
+
+Accessor to the auth attribute.
+Accepts an optional auth to be added to the auth array,
+always return the current auth array.
+
+The Auth defines an authentication scheme to be used. Any of the current
+authentication schemes used by the RIPE Database are allowed.
+
+=head2 B<admin_c( [$contact] )>
+
+Accessor to the admin_c attribute.
+Accepts an optional contact to be added to the admin_c array,
+always return the current admin_c array.
+
+The NIC-handle of an on-site administrative contact. As more than one person
+often fulfills a role function, there may be more than one admin_c listed.
+
+An administrative contact (admin_c) must be someone who is physically
+located at the site of the network.
+
+=head2 B<tech_c( [$contact] )>
+
+Accessor to the tech_c attribute.
+Accepts an optional contact to be added to the tech_c array,
+always return the current tech_c array.
+
+The NIC-handle of a technical contact. As more than one person often fulfills
+a role function, there may be more than one tech_c listed.
+
+A technical contact (tech_c) must be a person responsible for the
+day-to-day operation of the network, but does not need to be
+physically located at the site of the network.
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be added to the remarks array,
+always return the current remarks array.
+
+Information about the object that cannot be stated in other attributes.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+The email address to which notifications of changes to this object should
+be sent.
+
+=head2 B<mnt_by( [$mnt_by] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+always return the current mnt_by array.
+
+Lists a registered Mntner used to authorize and authenticate changes to
+this object.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+The email address of who last updated the database object and the date it
+occurred.
+
+Every time a change is made to a database object, this attribute will show
+the email address of the person who made those changes.
+Please use the address format specified in RFC 822 - Standard for
+the Format of ARPA Internet Text Message and provide the date
+format using one of the following two formats: YYYYMMDD or YYMMDD.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+The database where the object is registered.
+
+=head2 B<irt_nfy( [$irt_nfy] )>
+
+Accessor to the irt_nfy attribute.
+Accepts an optional irt_nfy value to be added to the irt_nfy array,
+always return the current irt_nfy array.
+
+The irt_nfy attribute specifies the email address to be notified when a
+reference to the irt object is added or removed.
+
+=cut
+
+1;
@@ -0,0 +1,261 @@
+package Net::Whois::Object::Irt::APNIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -t irt -h whois.afrinic.net
+# % This is the AfriNIC Whois server.
+# 
+# irt:            [mandatory]  [single]     [primary/look-up key]
+# address:        [mandatory]  [multiple]   [ ]
+# phone:          [optional]   [multiple]   [ ]
+# fax-no:         [optional]   [multiple]   [ ]
+# e-mail:         [mandatory]  [multiple]   [lookup key]
+# abuse-mailbox:  [mandatory]  [multiple]   [inverse key]
+# signature:      [optional]   [multiple]   [ ]
+# encryption:     [optional]   [multiple]   [ ]
+# org:            [optional]   [multiple]   [inverse key]
+# admin-c:        [mandatory]  [multiple]   [inverse key]
+# tech-c:         [mandatory]  [multiple]   [inverse key]
+# auth:           [mandatory]  [multiple]   [inverse key]
+# remarks:        [optional]   [multiple]   [ ]
+# irt-nfy:        [optional]   [multiple]   [inverse key]
+# notify:         [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+
+__PACKAGE__->attributes( 'primary',   [ 'irt' ] );
+__PACKAGE__->attributes( 'mandatory', [ 'irt', 'address', 'e_mail', 'abuse_mailbox', 'admin_c', 'tech_c', 'auth', 'mnt_by', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional',  [ 'phone', 'fax_no', 'signature', 'encryption', 'org', 'remarks', 'irt_nfy', 'notify' ] );
+__PACKAGE__->attributes( 'single',    [ 'irt', 'source' ] );
+__PACKAGE__->attributes( 'multiple',  [ 'address', 'phone', 'fax_no', 'e_mail', 'abuse_mailbox', 'signature', 'encryption', 'org', 'admin_c', 'tech_c', 'auth', 'remarks', 'irt_nfy', 'notify', 'mnt_by', 'changed' ] );
+
+=head1 NAME
+
+Net::Whois::Object::Irt::APNIC - an object representation of the RPSL Irt block
+
+=head1 DESCRIPTION
+
+The irt object is used to provide information about a Computer Security
+Incident Response Team (CSIRT).  IRTs or CSIRTs specifically respond to
+computer security incident reports and activity.
+
+They are dedicated abuse handling teams, (as distinct from network operational
+departments) which review and respond to abuse reports.
+
+=head1 METHODS
+
+=head2 B<new( %options )>
+
+Constructor for the Net::Whois::Object::Irt::APNIC class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+
+    return $self;
+
+}
+
+=head2 B<irt( [$irt] )>
+
+Accessor to the irt attribute.
+Accepts an optional irt, always return the current irt.
+
+The irt object name starts with "IRT-".
+
+=cut
+
+sub irt {
+    my ( $self, $irt ) = @_;
+    if ( $irt and $irt !~ /^IRT-/i ) {
+        warn "Irt name not valid ($irt) : Should start with 'IRT-'";
+    }
+    return $self->_single_attribute_setget( 'irt', $irt );
+}
+
+=head2 B<address( [$address] )>
+
+Accessor to the address attribute.
+Accepts an optional address to be added to the address array,
+always return the current address array.
+
+Full postal address of a contact.
+
+You can use any combination of alphanumeric characters.
+More than one line can be used.
+
+=cut
+
+sub address {
+    my ( $self, $address ) = @_;
+
+    return $self->_multiple_attribute_setget( 'address', $address );
+}
+
+=head2 B<phone( [$phone] )>
+
+Accessor to the phone attribute.
+Accepts an optional phone number to be added to the phone array,
+always return the current phone array.
+
+A contact telephone number.
+
++ <international code> <area code> <phone #>
+
++ <international code> <area code> <phone #> ext. <#>
+
+ EXAMPLE
+ phone: +681 368 0844 ext. 32
+
+=head2 B<fax_no( [$fax_no] )>
+
+Accessor to the fax_no attribute.
+Accepts an optional fax_no to be added to the fax_no array,
+always return the current fax_no array.
+
+A contact fax number.
+
++ <international code> <area code> <fax #>
+
+=head2 B<e_mail( [$e_mail] )>
+
+Accessor to the e_mail attribute.
+Accepts an optional e_mail to be added to the e_mail array,
+always return the current e_mail array.
+
+A contact email address for non-abuse/technical incidents.
+
+=head2 B<abuse_mailbox( [$abuse_mailbox] )>
+
+Accessor to the abuse_mailbox attribute.
+Accepts an optional abuse_mailbox to be added to the abuse_mailbox array,
+always return the current abuse_mailbox array.
+
+Specifies the email address to which abuse complaints should be sent.
+
+=head2 B<signature( [$signature] )>
+
+Accessor to the signature attribute.
+Accepts an optional signature to be added to the signature array,
+always return the current signature array.
+
+References a KeyCert object representing a CSIRT public key used by the
+team to sign their correspondence.
+
+=head2 B<encryption( [$encryption] )>
+
+Accessor to the encryption attribute.
+Accepts an optional encryption to be added to the encryption array,
+always return the current encryption array.
+
+References a KeyCert object representing a CSIRT public key used to encrypt
+correspondence sent to the CSIRT.
+
+=head2 B<org( [$org] )>
+
+Accessor to the org attribute.
+Accepts an optional org value to be added to the org array,
+always return the current org array.
+
+The organisation responsible for this resource.
+
+=head2 B<auth( [$auth] )>
+
+Accessor to the auth attribute.
+Accepts an optional auth to be added to the auth array,
+always return the current auth array.
+
+The Auth defines an authentication scheme to be used. Any of the current
+authentication schemes used by the RIPE Database are allowed.
+
+=head2 B<admin_c( [$contact] )>
+
+Accessor to the admin_c attribute.
+Accepts an optional contact to be added to the admin_c array,
+always return the current admin_c array.
+
+The NIC-handle of an on-site administrative contact. As more than one person
+often fulfills a role function, there may be more than one admin_c listed.
+
+An administrative contact (admin_c) must be someone who is physically
+located at the site of the network.
+
+=head2 B<tech_c( [$contact] )>
+
+Accessor to the tech_c attribute.
+Accepts an optional contact to be added to the tech_c array,
+always return the current tech_c array.
+
+The NIC-handle of a technical contact. As more than one person often fulfills
+a role function, there may be more than one tech_c listed.
+
+A technical contact (tech_c) must be a person responsible for the
+day-to-day operation of the network, but does not need to be
+physically located at the site of the network.
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be added to the remarks array,
+always return the current remarks array.
+
+Information about the object that cannot be stated in other attributes.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+The email address to which notifications of changes to this object should
+be sent.
+
+=head2 B<mnt_by( [$mnt_by] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+always return the current mnt_by array.
+
+Lists a registered Mntner used to authorize and authenticate changes to
+this object.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+The email address of who last updated the database object and the date it
+occurred.
+
+Every time a change is made to a database object, this attribute will show
+the email address of the person who made those changes.
+Please use the address format specified in RFC 822 - Standard for
+the Format of ARPA Internet Text Message and provide the date
+format using one of the following two formats: YYYYMMDD or YYMMDD.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+The database where the object is registered.
+
+=head2 B<irt_nfy( [$irt_nfy] )>
+
+Accessor to the irt_nfy attribute.
+Accepts an optional irt_nfy value to be added to the irt_nfy array,
+always return the current irt_nfy array.
+
+The irt_nfy attribute specifies the email address to be notified when a
+reference to the irt object is added or removed.
+
+=cut
+
+1;
@@ -0,0 +1,205 @@
+package Net::Whois::Object::KeyCert::AFRINIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -t key-cert -h whois.afrinic.net
+# % This is the AfriNIC Whois server.
+# 
+# key-cert:       [mandatory]  [single]     [primary/look-up key]
+# method:         [generated]  [single]     [ ]
+# owner:          [generated]  [multiple]   [ ]
+# fingerpr:       [generated]  [single]     [inverse key]
+# certif:         [mandatory]  [multiple]   [ ]
+# org:            [optional]   [multiple]   [inverse key]
+# remarks:        [optional]   [multiple]   [ ]
+# notify:         [optional]   [multiple]   [inverse key]
+# admin-c:        [optional]   [multiple]   [inverse key]
+# tech-c:         [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+
+__PACKAGE__->attributes( 'primary',   ['key_cert'] );
+__PACKAGE__->attributes( 'mandatory', [ 'key_cert', 'certif', 'mnt_by', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional', [ 'method', 'owner', 'fingerpr', 'org', 'remarks', 'notify', 'admin_c', 'tech_c' ] );
+__PACKAGE__->attributes( 'single', [ 'key_cert', 'method', 'fingerpr', 'source' ] );
+__PACKAGE__->attributes( 'multiple', [ 'owner', 'certif', 'org', 'remarks', 'notify', 'admin_c', 'tech_c', 'mnt_by', 'changed' ] );
+
+
+=head1 NAME
+
+Net::Whois::Object::KeyCert::AFRINIC - an object representation of the RPSL KeyCert block
+
+=head1 DESCRIPTION
+
+A key-cert object is a database public key certificate that is stored
+on the server and may be used with a mntner object for authentication
+when performing updates. Currently only PGP keys are supported.
+
+=head1 METHODS
+
+=head2 B<new( %options )>
+
+Constructor for the Net::Whois::Object::InetRtr class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+    return $self;
+}
+
+=head2 B<key_cert( [$key_cert] )>
+
+Accessor to the key_cert attribute.
+Accepts an optional key_cert value, always return the current key_cert value.
+
+For PGP KeyCert objects, the value of the key_cert attribute must be
+PGP-"key-id". These keys are compliant with the Open PGP Internet Standard.
+
+For X.509 KeyCert objects, the database software assigns this value as
+X.509-n. Here, 'n' is the next available number assigned by the software. If
+you want to create an X.509 KeyCert object, you should specify the value as
+AUTO-xx. If you delete an X.509 KeyCert object, it is not possible to
+recreate it with the same name.
+
+=head2 B<method( [$method] )>
+
+Accessor to the method attribute.
+Accepts an optional method, always return the current method value.
+
+The method attribute is generated by the software. 
+It is not necessary to include this attribute when you create or
+modify this object. If it is supplied, the software will check the value.
+If necessary the software will replace the supplied value with generated
+value. In this case a warning is returned to the user.
+
+=head2 B<owner( [$owner] )>
+
+Accessor to the owner attribute.
+Accepts an optional owner to be added to the owner array,
+always return the current owner array.
+
+The owner attribute is generated by the software. 
+It is not necessary to include this attribute when you create or
+modify this object. If it is supplied, the software will check the value.
+If necessary the software will replace the supplied value with generated
+value. In this case a warning is returned to the user.
+
+=head2 B<fingerpr( [$fingerpr] )>
+
+Accessor to the fingerpr attribute.
+Accepts an optional fingerpr, always return the current fingerpr.
+
+The fingerpr attribute is generated by the software. 
+It is not necessary to include this attribute when you create or
+modify this object. If it is supplied, the software will check the value.
+If necessary the software will replace the supplied value with generated
+value. In this case a warning is returned to the user.
+
+=head2 B<certif( [$certif] )>
+
+Accessor to the certif attribute.
+Accepts an optional certif to be added to the certif array,
+always return the current certif array.
+
+The certif attribute contains the public key. The value of the public key
+should be supplied either using multiple certif attributes, or in one
+certif attribute split over several lines. In the first case, this is
+easily done by exporting the key from your local key ring in ASCII armored
+format and adding the string certif to the start of each line of the key.
+In the second case, line continuation should be used to represent an ASCII
+armored format of the key. All the lines of the exported key must be included,
+as well as the start/end markers and the empty line which separates the header
+from the key body.
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be added to the remarks array,
+always return the current remarks array.
+
+General remarks. May include a URL or email address.
+
+=head2 B<org( [$org] )>
+
+Accessor to the org attribute.
+Accepts an optional org value to be added to the org array,
+always return the current org array.
+
+The organisation entity this object is bound to.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+The email address to which notifications of changes to this object should be
+sent.
+
+=head2 B<admin_c( [$contact] )>
+
+Accessor to the admin_c attribute.
+Accepts an optional contact to be added to the admin_c array,
+always return the current admin_c array.
+
+The NIC-handle of an on-site contact Person object. As more than one person
+often fulfills a role function, there may be more than one admin_c listed.
+
+An administrative contact (admin_c) must be someone who is physically
+located at the site of the network.
+
+=head2 B<tech_c( [$contact] )>
+
+Accessor to the tech_c attribute.
+Accepts an optional contact to be added to the tech_c array,
+always return the current tech_c array.
+
+The NIC-handle of a technical contact Person or Role object.  As more than
+one person often fulfills a role function, there may be more than one tech_c
+listed.
+
+A technical contact (tech_c) must be a person responsible for the
+day-to-day operation of the network, but does not need to be
+physically located at the site of the network.
+
+=head2 B<mnt_by( [$mnt_by] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+always return the current mnt_by array.
+
+Lists a registered Mntner used to authorize and authenticate changes to this
+object.
+
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+The email address of who last updated the database object and the date it
+occurred.
+
+Every time a change is made to a database object, this attribute will show
+the email address of the person who made those changes.
+Please use the address format specified in RFC 822 - Standard for
+the Format of ARPA Internet Text Message and provide the date
+format using one of the following two formats: YYYYMMDD or YYMMDD.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+The database where the object is registered.
+
+=cut
+
+1;
@@ -0,0 +1,208 @@
+ackage Net::Whois::Object::KeyCert::APNIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -h whois.apnic.net -t key-cert
+# % [whois.apnic.net]
+# % Whois data copyright terms    http://www.apnic.net/db/dbcopyright.html
+# 
+# key-cert:       [mandatory]  [single]     [primary/lookup key]
+# method:         [generated]  [single]     [ ]
+# owner:          [generated]  [multiple]   [ ]
+# fingerpr:       [generated]  [single]     [inverse key]
+# certif:         [mandatory]  [multiple]   [ ]
+# org:            [optional]   [multiple]   [inverse key]
+# remarks:        [optional]   [multiple]   [ ]
+# notify:         [optional]   [multiple]   [inverse key]
+# admin-c:        [optional]   [multiple]   [inverse key]
+# tech-c:         [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+# 
+# % This query was served by the APNIC Whois Service version 1.68.5 (WHOIS3)
+
+__PACKAGE__->attributes( 'primary',   [ 'key_cert' ] );
+__PACKAGE__->attributes( 'mandatory', [ 'key_cert', 'certif', 'mnt_by', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional',  [ 'method', 'owner', 'fingerpr', 'org', 'remarks', 'notify', 'admin_c', 'tech_c' ] );
+__PACKAGE__->attributes( 'single',    [ 'key_cert', 'method', 'fingerpr', 'source' ] );
+__PACKAGE__->attributes( 'multiple',  [ 'owner', 'certif', 'org', 'remarks', 'notify', 'admin_c', 'tech_c', 'mnt_by', 'changed' ] );
+
+
+=head1 NAME
+
+Net::Whois::Object::KeyCert::APNIC - an object representation of the RPSL KeyCert block
+
+=head1 DESCRIPTION
+
+A key-cert object is a database public key certificate that is stored
+on the server and may be used with a mntner object for authentication
+when performing updates. Currently only PGP keys are supported.
+
+=head1 METHODS
+
+=head2 B<new( %options )>
+
+Constructor for the Net::Whois::Object::InetRtr class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+    return $self;
+}
+
+=head2 B<key_cert( [$key_cert] )>
+
+Accessor to the key_cert attribute.
+Accepts an optional key_cert value, always return the current key_cert value.
+
+For PGP KeyCert objects, the value of the key_cert attribute must be
+PGP-"key-id". These keys are compliant with the Open PGP Internet Standard.
+
+For X.509 KeyCert objects, the database software assigns this value as
+X.509-n. Here, 'n' is the next available number assigned by the software. If
+you want to create an X.509 KeyCert object, you should specify the value as
+AUTO-xx. If you delete an X.509 KeyCert object, it is not possible to
+recreate it with the same name.
+
+=head2 B<method( [$method] )>
+
+Accessor to the method attribute.
+Accepts an optional method, always return the current method value.
+
+The method attribute is generated by the software. 
+It is not necessary to include this attribute when you create or
+modify this object. If it is supplied, the software will check the value.
+If necessary the software will replace the supplied value with generated
+value. In this case a warning is returned to the user.
+
+=head2 B<owner( [$owner] )>
+
+Accessor to the owner attribute.
+Accepts an optional owner to be added to the owner array,
+always return the current owner array.
+
+The owner attribute is generated by the software. 
+It is not necessary to include this attribute when you create or
+modify this object. If it is supplied, the software will check the value.
+If necessary the software will replace the supplied value with generated
+value. In this case a warning is returned to the user.
+
+=head2 B<fingerpr( [$fingerpr] )>
+
+Accessor to the fingerpr attribute.
+Accepts an optional fingerpr, always return the current fingerpr.
+
+The fingerpr attribute is generated by the software. 
+It is not necessary to include this attribute when you create or
+modify this object. If it is supplied, the software will check the value.
+If necessary the software will replace the supplied value with generated
+value. In this case a warning is returned to the user.
+
+=head2 B<certif( [$certif] )>
+
+Accessor to the certif attribute.
+Accepts an optional certif to be added to the certif array,
+always return the current certif array.
+
+The certif attribute contains the public key. The value of the public key
+should be supplied either using multiple certif attributes, or in one
+certif attribute split over several lines. In the first case, this is
+easily done by exporting the key from your local key ring in ASCII armored
+format and adding the string certif to the start of each line of the key.
+In the second case, line continuation should be used to represent an ASCII
+armored format of the key. All the lines of the exported key must be included,
+as well as the start/end markers and the empty line which separates the header
+from the key body.
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be added to the remarks array,
+always return the current remarks array.
+
+General remarks. May include a URL or email address.
+
+=head2 B<org( [$org] )>
+
+Accessor to the org attribute.
+Accepts an optional org value to be added to the org array,
+always return the current org array.
+
+The organisation entity this object is bound to.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+The email address to which notifications of changes to this object should be
+sent.
+
+=head2 B<admin_c( [$contact] )>
+
+Accessor to the admin_c attribute.
+Accepts an optional contact to be added to the admin_c array,
+always return the current admin_c array.
+
+The NIC-handle of an on-site contact Person object. As more than one person
+often fulfills a role function, there may be more than one admin_c listed.
+
+An administrative contact (admin_c) must be someone who is physically
+located at the site of the network.
+
+=head2 B<tech_c( [$contact] )>
+
+Accessor to the tech_c attribute.
+Accepts an optional contact to be added to the tech_c array,
+always return the current tech_c array.
+
+The NIC-handle of a technical contact Person or Role object.  As more than
+one person often fulfills a role function, there may be more than one tech_c
+listed.
+
+A technical contact (tech_c) must be a person responsible for the
+day-to-day operation of the network, but does not need to be
+physically located at the site of the network.
+
+=head2 B<mnt_by( [$mnt_by] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+always return the current mnt_by array.
+
+Lists a registered Mntner used to authorize and authenticate changes to this
+object.
+
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+The email address of who last updated the database object and the date it
+occurred.
+
+Every time a change is made to a database object, this attribute will show
+the email address of the person who made those changes.
+Please use the address format specified in RFC 822 - Standard for
+the Format of ARPA Internet Text Message and provide the date
+format using one of the following two formats: YYYYMMDD or YYMMDD.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+The database where the object is registered.
+
+=cut
+
+1;
@@ -0,0 +1,114 @@
+package Net::Whois::Object::Limerick::AFRINIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -t limerick -h whois.afrinic.net
+# % This is the AfriNIC Whois server.
+# 
+# limerick:       [mandatory]  [single]     [primary/look-up key]
+# descr:          [optional]   [multiple]   [ ]
+# text:           [mandatory]  [multiple]   [ ]
+# org:            [optional]   [multiple]   [inverse key]
+# admin-c:        [mandatory]  [multiple]   [inverse key]
+# author:         [mandatory]  [multiple]   [inverse key]
+# remarks:        [optional]   [multiple]   [ ]
+# notify:         [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+
+__PACKAGE__->attributes( 'primary', ['limerick'] );
+__PACKAGE__->attributes( 'mandatory', [ 'limerick', 'text', 'admin_c', 'author', 'mnt_by', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional', [ 'descr', 'org', 'remarks', 'notify' ] );
+__PACKAGE__->attributes( 'single', [ 'limerick', 'source' ] );
+__PACKAGE__->attributes( 'multiple', [ 'descr', 'text', 'org',  'admin_c', 'author', 'remarks', 'notify', 'mnt_by', 'changed' ] );
+
+=head1 NAME
+
+Net::Whois::Object::Limerick::AFRINIC - an object representation of the RPSL Limerick block
+
+=head1 DESCRIPTION
+
+The limerick object represents a humorous poem that has five lines and
+the rhyme scheme "aabba".
+
+=head1 METHODS
+
+=head2 B<new( %options )>
+
+Constructor for the Net::Whois::Object::Limerick::AFRINIC class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+
+    return $self;
+
+}
+
+=head2 B<limerick( [$limerick] )>
+
+Accessor to the limerick attribute.
+Accepts an optional value, always return the current limerick value.
+
+=head2 B<descr( [$descr] )>
+
+Accessor to the descr attribute.
+Accepts an optional descr to be added to the descr array,
+always return the current descr array.
+
+=head2 B<text( [$text] )>
+
+Accessor to the text attribute.
+Accepts an optional text to be added to the text array,
+always return the current text array.
+
+=head2 B<admin_c( [$contact] )>
+
+Accessor to the admin_c attribute.
+Accepts an optional contact to be added to the admin_c array,
+always return the current admin_c array.
+
+=head2 B<author( [$author] )>
+
+Accessor to the author attribute.
+Accepts an optional author to be added to the author array,
+always return the current author array.
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be added to the remarks array,
+always return the current remarks array.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+=head2 B<mnt_by( [$mnt_by] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+always return the current mnt_by array.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+=cut
+
+1;
@@ -2,7 +2,7 @@ package Net::Whois::Object::Limerick;
 
 use base qw/Net::Whois::Object/;
 
-# RIPE : Deprecated
+# RIPE: Deprecated
 #
 #
 # limerick:      [mandatory]  [single]     [primary/look-up key]
@@ -0,0 +1,237 @@
+package Net::Whois::Object::Mntner::AFRINIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -t mntner -h whois.afrinic.net
+# % This is the AfriNIC Whois server.
+# 
+# mntner:         [mandatory]  [single]     [primary/look-up key]
+# descr:          [mandatory]  [multiple]   [ ]
+# org:            [optional]   [multiple]   [inverse key]
+# admin-c:        [mandatory]  [multiple]   [inverse key]
+# tech-c:         [optional]   [multiple]   [inverse key]
+# upd-to:         [mandatory]  [multiple]   [inverse key]
+# mnt-nfy:        [optional]   [multiple]   [inverse key]
+# auth:           [mandatory]  [multiple]   [inverse key]
+# remarks:        [optional]   [multiple]   [ ]
+# notify:         [optional]   [multiple]   [inverse key]
+# abuse-mailbox:  [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+
+__PACKAGE__->attributes( 'primary', ['mntner'] );
+__PACKAGE__->attributes( 'mandatory', [ 'mntner', 'descr', 'admin_c', 'upd_to', 'auth', 'mnt_by', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional', [ 'org', 'tech_c', 'mnt_nfy', 'remarks', 'notify', 'abuse_mailbox' ] );
+__PACKAGE__->attributes( 'single', [ 'mntner', 'source' ] );
+__PACKAGE__->attributes( 'multiple', [ 'descr', 'org', 'admin_c', 'tech_c', 'upd_to', 'mnt_nfy', 'auth', 'remarks', 'notify', 'abuse_mailbox', 'mnt_by', 'changed' ] );
+
+=head1 NAME
+
+Net::Whois::Object::Mntner::AFRINIC - an object representation of the RPSL Mntner block
+
+=head1 DESCRIPTION
+
+Objects in the RIPE Database may be protected using Mntner (pronounced
+"maintainer") objects.  A Mntner object specifies authentication
+information required to authorise creation, deletion or modification
+of the objects protected by the Mntner.
+
+Objects are protected by a Mntner, if they contain a reference to the Mntner
+in the object. This is done by including a mnt-by attribute. Other
+attributes offer hierarchical protection. The mnt-by attribute is mandatory
+in all object types. Most users set the mnt-by value in a Mntner to
+reference itself.
+
+=head1 METHODS
+
+=head2 B<new( %options )>
+
+Constructor for the Net::Whois::Object::Mntner::AFRINIC class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+    return $self;
+}
+
+=head2 B<mntner( [$mntner] )>
+
+Accessor to the mntner attribute.
+Accepts an optional mntner value to be added to the mntner array,
+always return the current mntner.
+
+The unique name of a mntner object. APNIC recommends the following formats:
+
+Maintainer for resource registrations:
+
+<maint>-<iso3166-code>-<organization>
+
+ EXAMPLE 
+ MAINT-WF-SPARKYNET
+
+=head2 B<descr( [$descr] )>
+
+Accessor to the descr attribute.
+Accepts an optional descr line to be added to the descr array,
+always return the current descr array.
+
+A short description of the mntner object and the name of the organization
+associated with it.
+
+=head2 B<org( [$org] )>
+
+Accessor to the org attribute.
+Accepts an optional org value to be added to the org array,
+always return the current org array.
+
+The organisation this object is bound to.
+
+=head2 B<admin_c( [$contact] )>
+
+Accessor to the admin_c attribute.
+Accepts an optional contact to be added to the admin_c array,
+always return the current admin_c array.
+
+The NIC-handle of an on-site contact Person object. As more than one
+person often fulfills a role function, there may be more than one admin_c
+listed.
+
+An administrative contact (admin_c) must be someone who is
+physically located at the site of the network.
+
+=head2 B<tech_c( [$contact] )>
+
+Accessor to the tech_c attribute.
+Accepts an optional contact to be added to the tech_c array,
+always return the current tech_c array.
+
+The NIC-handle of a technical contact Person or Role object.  As more than
+one person often fulfills a role function, there may be more than one tech_c
+listed.
+
+A technical contact (tech_c) must be a person responsible for the
+day-to-day operation of the network, but does not need to be
+physically located at the site of the network.
+
+=head2 B<upd_to( [$upd_to] )>
+
+Accessor to the upd_to attribute.
+Accepts an optional upd_to value to be added to the upd_to array,
+always return the current upd_to array.
+
+The upd_to attribute specifies the email address to be notified when an
+attempt to update an object protected by this Mntner is unsuccessful.
+
+=head2 B<mnt_nfy( [$mnt_nfy] )>
+
+Accessor to the mnt_nfy attribute.
+Accepts an optional mnt_nfy value to be added to the mnt_nfy array,
+always return the current mnt_nfy array.
+
+The mnt_nfy attribute specifies the email address to be notified when an
+object protected by this Mntner is successfully updated.
+
+=head2 B<auth( [$auth] )>
+
+Accessor to the auth attribute.
+Accepts an optional auth value to be added to the auth array,
+always return the current auth array.
+
+The auth attribute defines an authentication scheme to be used. . Any of
+the current authentication schemes used by the RIPE Database are allowed.
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be addedt to the remarks array,
+always return the current remarks array.
+
+General remarks. May include a URL or email address.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+The email address to which notifications of changes to this object should
+be sent.
+
+=head2 B<mnt_by( [$mnt_by] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+always return the current mnt_by array.
+
+Lists a registered Mntner used to authorize and authenticate changes to
+this object.
+
+Most users set the mnt-by value in a Mntner to reference itself.
+
+=head2 B<auth_override( [$auth_override] )>
+
+Accessor to the auth_override attribute.
+Accepts an optional auth_override, always return the current auth_override.
+
+Routing Policy System Security specification defines an auth_override attribute
+in the Mntner object template. Together with referral-by attribute, they allow 
+for a Mntner to be modified if it becomes unresponsive. 
+As this is not part of the core functionality of the RIPE Database, 
+it has not been implemented in the current version of the database.
+
+=head2 B<referral_by( [$referral_by] )>
+
+Accessor to the referral_by attribute.
+Accepts an optional referral_by, always return the current referral_by.
+
+Routing Policy System Security specification defines an auth_override attribute
+in the Mntner object template. Together with referral-by attribute, they allow 
+for a Mntner to be modified if it becomes unresponsive. 
+As this is not part of the core functionality of the RIPE Database, 
+it has not been implemented in the current version of the database.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+The email address of who last updated the database object and the date it
+occurred.
+
+Every time a change is made to a database object, this attribute will show
+the email address of the person who made those changes.
+Please use the address format specified in RFC 822 - Standard for
+the Format of ARPA Internet Text Message and provide the date
+format using one of the following two formats: YYYYMMDD or YYMMDD.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+The name of the database from which the data was obtained.
+
+=head2 B<country( [$country] )>
+
+Accessor to the country attribute.
+Accepts an optional value, always return the current 'country'.
+Two letter ISO 3166 code of the country or economy where the admin-c is based.
+
+Please use UPPERCASE letters.
+
+=head2 B<abuse_mailbox( [$abuse_mailbox] )>
+
+Accessor to the abuse_mailbox attribute.
+Accepts an optional abuse_mailbox value to be added to the abuse_mailbox array,
+always return the current abuse_mailbox array.
+
+=cut
+
+1;
@@ -0,0 +1,242 @@
+package Net::Whois::Object::Mntner::APNIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -h whois.apnic.net -t mntner
+# % [whois.apnic.net]
+# % Whois data copyright terms    http://www.apnic.net/db/dbcopyright.html
+# 
+# mntner:         [mandatory]  [single]     [primary/lookup key]
+# descr:          [mandatory]  [multiple]   [ ]
+# country:        [optional]   [single]     [ ]
+# org:            [optional]   [multiple]   [inverse key]
+# admin-c:        [mandatory]  [multiple]   [inverse key]
+# tech-c:         [optional]   [multiple]   [inverse key]
+# upd-to:         [mandatory]  [multiple]   [inverse key]
+# mnt-nfy:        [optional]   [multiple]   [inverse key]
+# auth:           [mandatory]  [multiple]   [inverse key]
+# remarks:        [optional]   [multiple]   [ ]
+# notify:         [optional]   [multiple]   [inverse key]
+# abuse-mailbox:  [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [multiple]   [inverse key]
+# referral-by:    [mandatory]  [single]     [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+# 
+# % This query was served by the APNIC Whois Service version 1.68.5 (WHOIS4)
+
+__PACKAGE__->attributes( 'primary',   [ 'mntner' ] );
+__PACKAGE__->attributes( 'mandatory', [ 'mntner', 'descr', 'admin_c', 'upd_to', 'auth', 'mnt_by', 'referral_by', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional',  [ 'country', 'org', 'tech_c', 'mnt_nfy', 'remarks', 'notify', 'abuse_mailbox' ] );
+__PACKAGE__->attributes( 'single',    [ 'mntner', 'country', 'referral_by', 'source' ] );
+__PACKAGE__->attributes( 'multiple',  [ 'descr', 'org', 'admin_c', 'tech_c', 'upd_to', 'mnt_nfy', 'auth', 'remarks', 'notify', 'abuse_mailbox', 'mnt_by', 'changed' ] );
+
+=head1 NAME
+
+Net::Whois::Object::Mntner::APNIC - an object representation of the RPSL Mntner block
+
+=head1 DESCRIPTION
+
+Objects in the RIPE Database may be protected using Mntner (pronounced
+"maintainer") objects.  A Mntner object specifies authentication
+information required to authorise creation, deletion or modification
+of the objects protected by the Mntner.
+
+Objects are protected by a Mntner, if they contain a reference to the Mntner
+in the object. This is done by including a mnt-by attribute. Other
+attributes offer hierarchical protection. The mnt-by attribute is mandatory
+in all object types. Most users set the mnt-by value in a Mntner to
+reference itself.
+
+=head1 METHODS
+
+=head2 B<new( %options )>
+
+Constructor for the Net::Whois::Object::Mntner::APNIC class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+    return $self;
+}
+
+=head2 B<mntner( [$mntner] )>
+
+Accessor to the mntner attribute.
+Accepts an optional mntner value to be added to the mntner array,
+always return the current mntner.
+
+The unique name of a mntner object. APNIC recommends the following formats:
+
+Maintainer for resource registrations:
+
+<maint>-<iso3166-code>-<organization>
+
+ EXAMPLE 
+ MAINT-WF-SPARKYNET
+
+=head2 B<descr( [$descr] )>
+
+Accessor to the descr attribute.
+Accepts an optional descr line to be added to the descr array,
+always return the current descr array.
+
+A short description of the mntner object and the name of the organization
+associated with it.
+
+=head2 B<org( [$org] )>
+
+Accessor to the org attribute.
+Accepts an optional org value to be added to the org array,
+always return the current org array.
+
+The organisation this object is bound to.
+
+=head2 B<admin_c( [$contact] )>
+
+Accessor to the admin_c attribute.
+Accepts an optional contact to be added to the admin_c array,
+always return the current admin_c array.
+
+The NIC-handle of an on-site contact Person object. As more than one
+person often fulfills a role function, there may be more than one admin_c
+listed.
+
+An administrative contact (admin_c) must be someone who is
+physically located at the site of the network.
+
+=head2 B<tech_c( [$contact] )>
+
+Accessor to the tech_c attribute.
+Accepts an optional contact to be added to the tech_c array,
+always return the current tech_c array.
+
+The NIC-handle of a technical contact Person or Role object.  As more than
+one person often fulfills a role function, there may be more than one tech_c
+listed.
+
+A technical contact (tech_c) must be a person responsible for the
+day-to-day operation of the network, but does not need to be
+physically located at the site of the network.
+
+=head2 B<upd_to( [$upd_to] )>
+
+Accessor to the upd_to attribute.
+Accepts an optional upd_to value to be added to the upd_to array,
+always return the current upd_to array.
+
+The upd_to attribute specifies the email address to be notified when an
+attempt to update an object protected by this Mntner is unsuccessful.
+
+=head2 B<mnt_nfy( [$mnt_nfy] )>
+
+Accessor to the mnt_nfy attribute.
+Accepts an optional mnt_nfy value to be added to the mnt_nfy array,
+always return the current mnt_nfy array.
+
+The mnt_nfy attribute specifies the email address to be notified when an
+object protected by this Mntner is successfully updated.
+
+=head2 B<auth( [$auth] )>
+
+Accessor to the auth attribute.
+Accepts an optional auth value to be added to the auth array,
+always return the current auth array.
+
+The auth attribute defines an authentication scheme to be used. . Any of
+the current authentication schemes used by the RIPE Database are allowed.
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be addedt to the remarks array,
+always return the current remarks array.
+
+General remarks. May include a URL or email address.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+The email address to which notifications of changes to this object should
+be sent.
+
+=head2 B<mnt_by( [$mnt_by] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+always return the current mnt_by array.
+
+Lists a registered Mntner used to authorize and authenticate changes to
+this object.
+
+Most users set the mnt-by value in a Mntner to reference itself.
+
+=head2 B<auth_override( [$auth_override] )>
+
+Accessor to the auth_override attribute.
+Accepts an optional auth_override, always return the current auth_override.
+
+Routing Policy System Security specification defines an auth_override attribute
+in the Mntner object template. Together with referral-by attribute, they allow 
+for a Mntner to be modified if it becomes unresponsive. 
+As this is not part of the core functionality of the RIPE Database, 
+it has not been implemented in the current version of the database.
+
+=head2 B<referral_by( [$referral_by] )>
+
+Accessor to the referral_by attribute.
+Accepts an optional referral_by, always return the current referral_by.
+
+Routing Policy System Security specification defines an auth_override attribute
+in the Mntner object template. Together with referral-by attribute, they allow 
+for a Mntner to be modified if it becomes unresponsive. 
+As this is not part of the core functionality of the RIPE Database, 
+it has not been implemented in the current version of the database.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+The email address of who last updated the database object and the date it
+occurred.
+
+Every time a change is made to a database object, this attribute will show
+the email address of the person who made those changes.
+Please use the address format specified in RFC 822 - Standard for
+the Format of ARPA Internet Text Message and provide the date
+format using one of the following two formats: YYYYMMDD or YYMMDD.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+The name of the database from which the data was obtained.
+
+=head2 B<country( [$country] )>
+
+Accessor to the country attribute.
+Accepts an optional value, always return the current 'country'.
+Two letter ISO 3166 code of the country or economy where the admin-c is based.
+
+Please use UPPERCASE letters.
+
+=head2 B<abuse_mailbox( [$abuse_mailbox] )>
+
+Accessor to the abuse_mailbox attribute.
+Accepts an optional abuse_mailbox value to be added to the abuse_mailbox array,
+always return the current abuse_mailbox array.
+
+=cut
+
+1;
@@ -0,0 +1,191 @@
+package Net::Whois::Object::Organisation::AFRINIC;
+
+use base qw/Net::Whois::Object::Organisation/;
+
+# whois -h whois.afrinic.net -t organisation
+# 
+# % This is the AfriNIC Whois server.
+# 
+# organisation:   [mandatory]  [single]     [primary/look-up key]
+# org-name:       [mandatory]  [single]     [lookup key]
+# org-type:       [mandatory]  [single]     [ ]
+# descr:          [optional]   [multiple]   [ ]
+# country:        [mandatory]  [multiple]   [ ]
+# remarks:        [optional]   [multiple]   [ ]
+# address:        [mandatory]  [multiple]   [ ]
+# phone:          [optional]   [multiple]   [ ]
+# fax-no:         [optional]   [multiple]   [ ]
+# e-mail:         [mandatory]  [multiple]   [lookup key]
+# org:            [optional]   [multiple]   [inverse key]
+# admin-c:        [optional]   [multiple]   [inverse key]
+# tech-c:         [optional]   [multiple]   [inverse key]
+# ref-nfy:        [optional]   [multiple]   [inverse key]
+# mnt-ref:        [mandatory]  [multiple]   [inverse key]
+# notify:         [optional]   [multiple]   [inverse key]
+# abuse-mailbox:  [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+
+__PACKAGE__->attributes( 'primary',   ['organisation'] );
+__PACKAGE__->attributes( 'mandatory', [ 'organisation', 'org_name', 'org_type', 'country', 'address', 'e_mail', 'mnt_ref', 'mnt_by', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional',  [ 'descr', 'remarks', 'phone', 'fax_no', 'org', 'admin_c', 'tech_c', 'ref_nfy', 'notify', 'abuse_mailbox' ] );
+__PACKAGE__->attributes( 'single', [ 'organisation', 'org_name', 'org_type', 'source' ] );
+__PACKAGE__->attributes( 'multiple', [ 'descr', 'country', 'remarks', 'address', 'phone', 'fax_no', 'e_mail', 'org', 'admin_c', 'tech_c', 'ref_nfy', 'mnt_ref', 'notify','abuse_mailbox', 'mnt_by', 'changed' ] );
+
+=head1 NAME
+
+Net::Whois::Object::Organisation - an object representation of the RPSL Organisation block
+
+=head1 DESCRIPTION
+
+The organisation object is designed to provide an easy way of mapping resources to a particular organisaiton.
+
+=head1 METHODS
+
+=head2 B<new( %options )>
+
+Constructor for the Net::Whois::Object::Organisation class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+    return $self;
+}
+
+=head2 B<organisation( [$organisation] )>
+
+Accessor to the organisation attribute.
+Accepts an optional organisation, always return the current organisation.
+
+=head2 B<org_name( [$org_name] )>
+
+Accessor to the org_name attribute.
+Accepts an optional org_name, always return the current org_name.
+
+=head2 B<org_type( [$org_type] )>
+
+Accessor to the org_type attribute.
+Accepts an optional org_type, always return the current org_type.
+
+Possible values are:
+IANA for Internet Assigned Numbers Authority, RIR for Regional Internet
+Registries, NIR for National Internet Registries, LIR for Local Internet
+Registries, and OTHER for all other organisations. 
+
+=head2 B<org( [$org] )>
+
+Accessor to the org attribute.
+Accepts an optional org, always return the current org.
+
+Points to an existing organisation object representing the entity that
+holds the resource.
+
+The 'ORG-' string followed by 2 to 4 characters, followed by up to 5 digits
+followed by a source specification.  The first digit must not be "0".
+Source specification starts with "-" followed by source name up to
+9-character length.
+
+=head2 B<address( [$address] )>
+
+Accessor to the address attribute.
+Accepts an optional address line to be added to the address array,
+always return the current address array.
+
+=head2 B<phone( [$phone] )>
+
+Accessor to the phone attribute.
+Accepts an optional phone number to be added to the phone array,
+always return the current phone array.
+
+=head2 B<fax_no( [$fax_no] )>
+
+Accessor to the fax_no attribute.
+Accepts an optional fax_no to be added to the fax_no array,
+always return the current fax_no array.
+
+=head2 B<e_mail( [$e_mail] )>
+
+Accessor to the e_mail attribute.
+Accepts an optional e_mail to be added to the e_mail array,
+always return the current e_mail array.
+
+=head2 B<country( [$country] )>
+
+Accessor to the country attribute.
+Accepts an optional country to be added to the country array,
+always return the current country array.
+
+=head2 B<language( [$language] )>
+
+Accessor to the language attribute.
+Accepts an optional language to be added to the language array,
+always return the current language array.
+
+=head2 B<admin_c( [$contact] )>
+
+Accessor to the admin_c attribute.
+Accepts an optional contact to be added to the admin_c array,
+always return the current admin_c array.
+
+=head2 B<tech_c( [$contact] )>
+
+Accessor to the tech_c attribute.
+Accepts an optional contact to be added to the tech_c array,
+always return the current tech_c array.
+
+=head2 B<descr( [$descr] )>
+
+Accessor to the descr attribute.
+Accepts an optional descr line to be added to the descr array,
+always return the current descr array.
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be added to the remarks array,
+always return the current remarks array.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+=head2 B<mnt_by( [$mnt_by] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+always return the current mnt_by array.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+=head2 B<ref_nfy( [$ref_nfy] )>
+
+Accessor to the ref_nfy attribute.
+Accepts an optional ref_nfy value to be added to the ref_nfy array,
+always return the current ref_nfy array.
+
+=head2 B<mnt_ref( [$mnt_ref] )>
+
+Accessor to the mnt_ref attribute.
+Accepts an optional mnt_ref value to be added to the mnt_ref array,
+always return the current mnt_ref array.
+
+=cut
+
+1;
@@ -0,0 +1,194 @@
+package Net::Whois::Object::Organisation::APNIC;
+
+use base qw/Net::Whois::Object::Organisation/;
+
+# whois -h whois.apnic.net -t organisation
+# % [whois.apnic.net]
+# % Whois data copyright terms    http://www.apnic.net/db/dbcopyright.html
+# 
+# organisation:   [mandatory]  [single]     [primary/lookup key]
+# org-name:       [mandatory]  [single]     [lookup key]
+# org-type:       [mandatory]  [single]     [ ]
+# descr:          [optional]   [multiple]   [ ]
+# country:        [optional]   [multiple]   [ ]
+# address:        [mandatory]  [multiple]   [ ]
+# phone:          [optional]   [multiple]   [ ]
+# fax-no:         [optional]   [multiple]   [ ]
+# e-mail:         [mandatory]  [multiple]   [lookup key]
+# geoloc:         [optional]   [single]     [ ]
+# language:       [optional]   [multiple]   [ ]
+# org:            [optional]   [multiple]   [inverse key]
+# admin-c:        [optional]   [multiple]   [inverse key]
+# tech-c:         [optional]   [multiple]   [inverse key]
+# ref-nfy:        [optional]   [multiple]   [inverse key]
+# mnt-ref:        [mandatory]  [multiple]   [inverse key]
+# notify:         [optional]   [multiple]   [inverse key]
+# abuse-mailbox:  [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+# 
+# % This query was served by the APNIC Whois Service version 1.68.5 (WHOIS2)
+
+__PACKAGE__->attributes( 'primary',   [ 'organisation' ] );
+__PACKAGE__->attributes( 'mandatory', [ 'organisation', 'org_name', 'org_type', 'address', 'e_mail', 'mnt_ref', 'mnt_by', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional',  [ 'descr', 'country', 'phone', 'fax_no', 'geoloc', 'language', 'org', 'admin_c', 'tech_c', 'ref_nfy', 'notify', 'abuse_mailbox' ] );
+__PACKAGE__->attributes( 'single',    [ 'organisation', 'org_name', 'org_type', 'geoloc', 'source' ] );
+__PACKAGE__->attributes( 'multiple',  [ 'descr', 'country', 'address', 'phone', 'fax_no', 'e_mail', 'language', 'org', 'admin_c', 'tech_c', 'ref_nfy', 'mnt_ref', 'notify', 'abuse_mailbox', 'mnt_by', 'changed' ] );
+
+=head1 NAME
+
+Net::Whois::Object::Organisation - an object representation of the RPSL Organisation block
+
+=head1 DESCRIPTION
+
+The organisation object is designed to provide an easy way of mapping resources to a particular organisaiton.
+
+=head1 METHODS
+
+=head2 B<new( %options )>
+
+Constructor for the Net::Whois::Object::Organisation class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+    return $self;
+}
+
+=head2 B<organisation( [$organisation] )>
+
+Accessor to the organisation attribute.
+Accepts an optional organisation, always return the current organisation.
+
+=head2 B<org_name( [$org_name] )>
+
+Accessor to the org_name attribute.
+Accepts an optional org_name, always return the current org_name.
+
+=head2 B<org_type( [$org_type] )>
+
+Accessor to the org_type attribute.
+Accepts an optional org_type, always return the current org_type.
+
+Possible values are:
+IANA for Internet Assigned Numbers Authority, RIR for Regional Internet
+Registries, NIR for National Internet Registries, LIR for Local Internet
+Registries, and OTHER for all other organisations. 
+
+=head2 B<org( [$org] )>
+
+Accessor to the org attribute.
+Accepts an optional org, always return the current org.
+
+Points to an existing organisation object representing the entity that
+holds the resource.
+
+The 'ORG-' string followed by 2 to 4 characters, followed by up to 5 digits
+followed by a source specification.  The first digit must not be "0".
+Source specification starts with "-" followed by source name up to
+9-character length.
+
+=head2 B<address( [$address] )>
+
+Accessor to the address attribute.
+Accepts an optional address line to be added to the address array,
+always return the current address array.
+
+=head2 B<phone( [$phone] )>
+
+Accessor to the phone attribute.
+Accepts an optional phone number to be added to the phone array,
+always return the current phone array.
+
+=head2 B<fax_no( [$fax_no] )>
+
+Accessor to the fax_no attribute.
+Accepts an optional fax_no to be added to the fax_no array,
+always return the current fax_no array.
+
+=head2 B<e_mail( [$e_mail] )>
+
+Accessor to the e_mail attribute.
+Accepts an optional e_mail to be added to the e_mail array,
+always return the current e_mail array.
+
+=head2 B<country( [$country] )>
+
+Accessor to the country attribute.
+Accepts an optional country to be added to the country array,
+always return the current country array.
+
+=head2 B<language( [$language] )>
+
+Accessor to the language attribute.
+Accepts an optional language to be added to the language array,
+always return the current language array.
+
+=head2 B<admin_c( [$contact] )>
+
+Accessor to the admin_c attribute.
+Accepts an optional contact to be added to the admin_c array,
+always return the current admin_c array.
+
+=head2 B<tech_c( [$contact] )>
+
+Accessor to the tech_c attribute.
+Accepts an optional contact to be added to the tech_c array,
+always return the current tech_c array.
+
+=head2 B<descr( [$descr] )>
+
+Accessor to the descr attribute.
+Accepts an optional descr line to be added to the descr array,
+always return the current descr array.
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be added to the remarks array,
+always return the current remarks array.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+=head2 B<mnt_by( [$mnt_by] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+always return the current mnt_by array.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+=head2 B<ref_nfy( [$ref_nfy] )>
+
+Accessor to the ref_nfy attribute.
+Accepts an optional ref_nfy value to be added to the ref_nfy array,
+always return the current ref_nfy array.
+
+=head2 B<mnt_ref( [$mnt_ref] )>
+
+Accessor to the mnt_ref attribute.
+Accepts an optional mnt_ref value to be added to the mnt_ref array,
+always return the current mnt_ref array.
+
+=cut
+
+1;
@@ -2,13 +2,13 @@ package Net::Whois::Object::Organisation;
 
 use base qw/Net::Whois::Object/;
 
-# From  : whois -t organisation
+# whois -h whois.ripe.net -t organisation
 # % This is the RIPE Database query service.
 # % The objects are in RPSL format.
 # %
 # % The RIPE Database is subject to Terms and Conditions.
 # % See http://www.ripe.net/db/support/db-terms-conditions.pdf
-#
+# 
 # organisation:   [mandatory]  [single]     [primary/lookup key]
 # org-name:       [mandatory]  [single]     [lookup key]
 # org-type:       [mandatory]  [single]     [ ]
@@ -23,6 +23,7 @@ use base qw/Net::Whois::Object/;
 # org:            [optional]   [multiple]   [inverse key]
 # admin-c:        [optional]   [multiple]   [inverse key]
 # tech-c:         [optional]   [multiple]   [inverse key]
+# abuse-c:        [optional]   [single]     [inverse key]
 # ref-nfy:        [optional]   [multiple]   [inverse key]
 # mnt-ref:        [mandatory]  [multiple]   [inverse key]
 # notify:         [optional]   [multiple]   [inverse key]
@@ -30,12 +31,14 @@ use base qw/Net::Whois::Object/;
 # mnt-by:         [mandatory]  [multiple]   [inverse key]
 # changed:        [mandatory]  [multiple]   [ ]
 # source:         [mandatory]  [single]     [ ]
+# 
+# % This query was served by the RIPE Database Query Service version 1.69 (WHOIS4)
 
-__PACKAGE__->attributes( 'primary',   ['organisation'] );
+__PACKAGE__->attributes( 'primary',   [ 'organisation' ] );
 __PACKAGE__->attributes( 'mandatory', [ 'organisation', 'org_name', 'org_type', 'address', 'e_mail', 'mnt_ref', 'mnt_by', 'changed', 'source' ] );
-__PACKAGE__->attributes( 'optional',  [ 'descr', 'remarks', 'phone', 'fax_no', 'geoloc', 'language', 'org', 'admin_c', 'tech_c', 'ref_nfy', 'notify', 'abuse_mailbox' ] );
-__PACKAGE__->attributes( 'single', [ 'organisation', 'org_name', 'org_type', 'geoloc','source' ] );
-__PACKAGE__->attributes( 'multiple', [ 'descr', 'remarks', 'address', 'phone', 'fax_no', 'e_mail','language', 'org', 'admin_c', 'tech_c', 'ref_nfy', 'mnt_ref', 'notify','abuse_mailbox', 'mnt_by', 'changed' ] );
+__PACKAGE__->attributes( 'optional',  [ 'descr', 'remarks', 'phone', 'fax_no', 'geoloc', 'language', 'org', 'abuse_c', 'admin_c', 'tech_c', 'ref_nfy', 'notify', 'abuse_mailbox' ] );
+__PACKAGE__->attributes( 'single',    [ 'organisation', 'org_name', 'org_type', 'geoloc', 'abuse_c', 'source' ] );
+__PACKAGE__->attributes( 'multiple',  [ 'descr', 'remarks', 'address', 'phone', 'fax_no', 'e_mail','language', 'org', 'admin_c', 'tech_c', 'ref_nfy', 'mnt_ref', 'notify','abuse_mailbox', 'mnt_by', 'changed' ] );
 
 =head1 NAME
 
@@ -77,7 +80,7 @@ Accepts an optional org_name, always return the current org_name.
 Accessor to the org_type attribute.
 Accepts an optional org_type, always return the current org_type.
 
-Possible values are :
+Possible values are:
 IANA for Internet Assigned Numbers Authority, RIR for Regional Internet
 Registries, NIR for National Internet Registries, LIR for Local Internet
 Registries, and OTHER for all other organisations. 
@@ -136,6 +139,12 @@ Accessor to the admin_c attribute.
 Accepts an optional contact to be added to the admin_c array,
 always return the current admin_c array.
 
+=head2 B<abuse_c( [$contact] )>
+
+Accessor to the abuse_c attribute.
+Accepts an optional contact to be added to the abuse_c array,
+always return the current abuse_c array.
+
 =head2 B<tech_c( [$contact] )>
 
 Accessor to the tech_c attribute.
@@ -0,0 +1,143 @@
+package Net::Whois::Object::PeeringSet::AFRINIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -t peering-set -h whois.afrinic.net
+# % This is the AfriNIC Whois server.
+# 
+# peering-set:    [mandatory]  [single]     [primary/look-up key]
+# descr:          [mandatory]  [multiple]   [ ]
+# peering:        [optional]   [multiple]   [ ]
+# mp-peering:     [optional]   [multiple]   [ ]
+# remarks:        [optional]   [multiple]   [ ]
+# org:            [optional]   [multiple]   [inverse key]
+# tech-c:         [mandatory]  [multiple]   [inverse key]
+# admin-c:        [mandatory]  [multiple]   [inverse key]
+# notify:         [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [multiple]   [inverse key]
+# mnt-lower:      [optional]   [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+
+__PACKAGE__->attributes( 'primary', ['peering_set'] );
+__PACKAGE__->attributes( 'mandatory', [ 'peering_set', 'descr', 'tech_c', 'admin_c', 'mnt_by', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional', [ 'peering', 'mp_peering', 'remarks', 'org', 'notify', 'mnt_lower' ] );
+__PACKAGE__->attributes( 'single',    [ 'peering_set', 'source' ] );
+__PACKAGE__->attributes( 'multiple',  [ 'descr', 'peering', 'mp_peering', 'remarks', 'org', 'tech_c', 'admin_c', 'notify', 'mnt_by', 'mnt_lower', 'changed' ] );
+
+
+=head1 NAME
+
+Net::Whois::Object::PeeringSet::AFRINIC - an object representation of the RPSL PeeringSet block
+
+=head1 DESCRIPTION
+
+A peering-set object defines a set of peerings that are listed in its
+"peering:" attributes.  The "peering-set:" attribute defines the name
+of the set.  It is an RPSL name that starts with "prng-".
+
+=head1 METHODS
+
+=head2 B<new( %options )>
+
+Constructor for the Net::Whois::Object::PeeringSet::AFRINIC class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+    return $self;
+}
+
+=head2 B<peering_set( [$peering_set] )>
+
+Accessor to the peering_set attribute (the name of the filter set).
+Accepts an optional peering_set, always return the current peering_set.
+
+The peering_set must begin with 'PRNG-'.
+
+=head2 B<descr( [$descr] )>
+
+Accessor to the descr attribute.
+Accepts an optional descr line to be added to the descr array,
+always return the current descr array.
+
+=head2 B<peering( [$peering] )>
+
+Accessor to the peering attribute.
+Accepts an optional peering value to be added to the peering array,
+always return the current peering array.
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be added to the remarks array,
+always return the current remarks array.
+
+=head2 B<org( [$org] )>
+
+Accessor to the org attribute.
+Accepts an optional org, always return the current org.
+
+Points to an existing organisation object representing the entity that
+holds the resource.
+
+The 'ORG-' string followed by 2 to 4 characters, followed by up to 5 digits
+followed by a source specification.  The first digit must not be "0".
+Source specification starts with "-" followed by source name up to
+9-character length.
+
+=head2 B<tech_c( [$contact] )>
+
+Accessor to the tech_c attribute.
+Accepts an optional contact to be added to the tech_c array,
+always return the current tech_c array.
+
+=head2 B<admin_c( [$contact] )>
+
+Accessor to the admin_c attribute.
+Accepts an optional contact to be added to the admin_c array,
+always return the current admin_c array.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+=head2 B<mnt_by( [$mnt_by] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+        always return the current 'mnt_by' array.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+=head2 B<mp_peering( [$mp_peering] )>
+
+Accessor to the mp_peering attribute.
+Accepts an optional mp_peering value to be added to the mp_peering array,
+always return the current mp_peering array.
+
+=head2 B<mnt_lower( [$mnt_lower] )>
+
+Accessor to the mnt_lower attribute.
+Accepts an optional mnt_lower value to be added to the mnt_lower array,
+always return the current mnt_lower array.
+
+=cut
+
+1;
@@ -0,0 +1,147 @@
+package Net::Whois::Object::PeeringSet::APNIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -h whois.apnic.net -t peering-set
+# % [whois.apnic.net]
+# % Whois data copyright terms    http://www.apnic.net/db/dbcopyright.html
+# 
+# peering-set:    [mandatory]  [single]     [primary/lookup key]
+# descr:          [mandatory]  [multiple]   [ ]
+# peering:        [optional]   [multiple]   [ ]
+# mp-peering:     [optional]   [multiple]   [ ]
+# remarks:        [optional]   [multiple]   [ ]
+# org:            [optional]   [multiple]   [inverse key]
+# tech-c:         [mandatory]  [multiple]   [inverse key]
+# admin-c:        [mandatory]  [multiple]   [inverse key]
+# notify:         [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [multiple]   [inverse key]
+# mnt-lower:      [optional]   [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+# 
+# % This query was served by the APNIC Whois Service version 1.68.5 (WHOIS1)
+
+
+__PACKAGE__->attributes( 'primary',   [ 'peering_set' ] );
+__PACKAGE__->attributes( 'mandatory', [ 'peering_set', 'descr', 'tech_c', 'admin_c', 'mnt_by', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional',  [ 'peering', 'mp_peering', 'remarks', 'org', 'notify', 'mnt_lower' ] );
+__PACKAGE__->attributes( 'single',    [ 'peering_set', 'source' ] );
+__PACKAGE__->attributes( 'multiple',  [ 'descr', 'peering', 'mp_peering', 'remarks', 'org', 'tech_c', 'admin_c', 'notify', 'mnt_by', 'mnt_lower', 'changed' ] );
+
+
+=head1 NAME
+
+Net::Whois::Object::PeeringSet::APNIC - an object representation of the RPSL PeeringSet block
+
+=head1 DESCRIPTION
+
+A peering-set object defines a set of peerings that are listed in its
+"peering:" attributes.  The "peering-set:" attribute defines the name
+of the set.  It is an RPSL name that starts with "prng-".
+
+=head1 METHODS
+
+=head2 B<new( %options )>
+
+Constructor for the Net::Whois::Object::PeeringSet::APNIC class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+    return $self;
+}
+
+=head2 B<peering_set( [$peering_set] )>
+
+Accessor to the peering_set attribute (the name of the filter set).
+Accepts an optional peering_set, always return the current peering_set.
+
+The peering_set must begin with 'PRNG-'.
+
+=head2 B<descr( [$descr] )>
+
+Accessor to the descr attribute.
+Accepts an optional descr line to be added to the descr array,
+always return the current descr array.
+
+=head2 B<peering( [$peering] )>
+
+Accessor to the peering attribute.
+Accepts an optional peering value to be added to the peering array,
+always return the current peering array.
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be added to the remarks array,
+always return the current remarks array.
+
+=head2 B<org( [$org] )>
+
+Accessor to the org attribute.
+Accepts an optional org, always return the current org.
+
+Points to an existing organisation object representing the entity that
+holds the resource.
+
+The 'ORG-' string followed by 2 to 4 characters, followed by up to 5 digits
+followed by a source specification.  The first digit must not be "0".
+Source specification starts with "-" followed by source name up to
+9-character length.
+
+=head2 B<tech_c( [$contact] )>
+
+Accessor to the tech_c attribute.
+Accepts an optional contact to be added to the tech_c array,
+always return the current tech_c array.
+
+=head2 B<admin_c( [$contact] )>
+
+Accessor to the admin_c attribute.
+Accepts an optional contact to be added to the admin_c array,
+always return the current admin_c array.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+=head2 B<mnt_by( [$mnt_by] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+        always return the current 'mnt_by' array.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+=head2 B<mp_peering( [$mp_peering] )>
+
+Accessor to the mp_peering attribute.
+Accepts an optional mp_peering value to be added to the mp_peering array,
+always return the current mp_peering array.
+
+=head2 B<mnt_lower( [$mnt_lower] )>
+
+Accessor to the mnt_lower attribute.
+Accepts an optional mnt_lower value to be added to the mnt_lower array,
+always return the current mnt_lower array.
+
+=cut
+
+1;
@@ -5,7 +5,7 @@ use base qw/Net::Whois::Object/;
 # http://www.ripe.net/data-tools/support/documentation/update-ref-manual#section-19
 # http://www.apnic.net/apnic-info/whois_search/using-whois/guide/peering-set
 #
-# From : whois -t peering-set 
+# From: whois -t peering-set 
 # % This is the RIPE Database query service.
 # % The objects are in RPSL format.
 # %
@@ -0,0 +1,141 @@
+package Net::Whois::Object::Person::AFRINIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -t person -h whois.afrinic.net
+# % This is the AfriNIC Whois server.
+# 
+# person:         [mandatory]  [single]     [lookup key]
+# address:        [mandatory]  [multiple]   [ ]
+# phone:          [mandatory]  [multiple]   [ ]
+# fax-no:         [optional]   [multiple]   [ ]
+# e-mail:         [mandatory]  [multiple]   [lookup key]
+# org:            [optional]   [multiple]   [inverse key]
+# nic-hdl:        [mandatory]  [single]     [primary/look-up key]
+# remarks:        [optional]   [multiple]   [ ]
+# notify:         [optional]   [multiple]   [inverse key]
+# abuse-mailbox:  [optional]   [multiple]   [inverse key]
+# mnt-by:         [optional]   [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+
+__PACKAGE__->attributes( 'primary', ['nic_hdl'] );
+__PACKAGE__->attributes( 'mandatory', [ 'person', 'address', 'phone', 'email', 'nic_hdl', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional', [ 'fax_no', 'org', 'remarks', 'notify', 'abuse_mailbox', 'mnt_by' ] );
+__PACKAGE__->attributes( 'single', [ 'person', 'nic_hdl', 'source' ] );
+__PACKAGE__->attributes( 'multiple', [ 'address', 'phone', 'fax_no', 'e_mail', 'org', 'remarks', 'notify', 'abuse_mailbox', 'mnt_by', 'changed' ] );
+
+
+=head1 NAME
+
+Net::Whois::Object::Person::AFRINIC - an object representation of the RPSL Person block
+
+=head1 DESCRIPTION
+
+A person object contains information about technical or administrative
+contact responsible for the object where it is referenced. Once the
+object is created, the value of the "person:" attribute cannot be
+changed.
+
+=head1 METHODS
+
+=head2 B<new( %options )>
+
+Constructor for the Net::Whois::Object::Person::AFRINIC class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+    return $self;
+}
+
+=head2 B<person( [$person] )>
+
+Accessor to the person attribute.
+Accepts an optional person, always return the current person.
+
+=head2 B<address( [$address] )>
+
+Accessor to the address attribute.
+Accepts an optional address line to be added to the address array,
+always return the current address array.
+
+=head2 B<phone( [$phone] )>
+
+Accessor to the phone attribute.
+Accepts an optional phone number to be added to the phone array,
+always return the current phone array.
+
+=head2 B<fax_no( [$fax_no] )>
+
+Accessor to the fax_no attribute.
+Accepts an optional fax_no to be added to the fax_no array,
+always return the current fax_no array.
+
+=head2 B<e_mail( [$e_mail] )>
+
+Accessor to the e_mail attribute.
+Accepts an optional e_mail to be added to the e_mail array,
+always return the current e_mail array.
+
+=head2 B<org( [$org] )>
+
+Accessor to the org attribute.
+Accepts an optional org, always return the current org array.
+
+Points to an existing organisation object representing the entity that
+holds the resource.
+
+The 'ORG-' string followed by 2 to 4 characters, followed by up to 5 digits
+followed by a source specification.  The first digit must not be "0".
+Source specification starts with "-" followed by source name up to
+9-character length.
+
+=head2 B<nic_hdl( [$nic_hdl] )>
+
+Accessor to the nic_hdl attribute.
+Accepts an optional nic_hdl, always return the current nic_hdl.
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be added to the remarks array,
+always return the current remarks array.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+=head2 B<abuse_mailbox( [$abuse_mailbox] )>
+
+Accessor to the abuse_mailbox attribute.
+Accepts an optional abuse_mailbox value to be added to the abuse_mailbox array,
+always return the current abuse_mailbox array.
+
+=head2 B<mnt_by( [$mnt_by] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+always return the current mnt_by array.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+=cut
+
+1;
@@ -0,0 +1,145 @@
+package Net::Whois::Object::Person::APNIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -h whois.apnic.net -t person
+# % [whois.apnic.net]
+# % Whois data copyright terms    http://www.apnic.net/db/dbcopyright.html
+# 
+# person:         [mandatory]  [single]     [lookup key]
+# address:        [mandatory]  [multiple]   [ ]
+# country:        [mandatory]  [single]     [ ]
+# phone:          [mandatory]  [multiple]   [ ]
+# fax-no:         [optional]   [multiple]   [ ]
+# e-mail:         [mandatory]  [multiple]   [lookup key]
+# org:            [optional]   [multiple]   [inverse key]
+# nic-hdl:        [mandatory]  [single]     [primary/lookup key]
+# remarks:        [optional]   [multiple]   [ ]
+# notify:         [optional]   [multiple]   [inverse key]
+# abuse-mailbox:  [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+# 
+# % This query was served by the APNIC Whois Service version 1.68.5 (WHOIS1)
+
+__PACKAGE__->attributes( 'primary',   [ 'nic_hdl' ] );
+__PACKAGE__->attributes( 'mandatory', [ 'person', 'address', 'country', 'phone', 'email', 'nic_hdl', 'mnt_by', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional',  [ 'fax_no', 'org', 'remarks', 'notify', 'abuse_mailbox' ] );
+__PACKAGE__->attributes( 'single',    [ 'person', 'country', 'nic_hdl', 'source' ] );
+__PACKAGE__->attributes( 'multiple',  [ 'address', 'phone', 'fax_no', 'e_mail', 'org', 'remarks', 'notify', 'abuse_mailbox', 'mnt_by', 'changed' ] );
+
+
+=head1 NAME
+
+Net::Whois::Object::Person::APNIC - an object representation of the RPSL Person block
+
+=head1 DESCRIPTION
+
+A person object contains information about technical or administrative
+contact responsible for the object where it is referenced. Once the
+object is created, the value of the "person:" attribute cannot be
+changed.
+
+=head1 METHODS
+
+=head2 B<new( %options )>
+
+Constructor for the Net::Whois::Object::Person::APNIC class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+    return $self;
+}
+
+=head2 B<person( [$person] )>
+
+Accessor to the person attribute.
+Accepts an optional person, always return the current person.
+
+=head2 B<address( [$address] )>
+
+Accessor to the address attribute.
+Accepts an optional address line to be added to the address array,
+always return the current address array.
+
+=head2 B<phone( [$phone] )>
+
+Accessor to the phone attribute.
+Accepts an optional phone number to be added to the phone array,
+always return the current phone array.
+
+=head2 B<fax_no( [$fax_no] )>
+
+Accessor to the fax_no attribute.
+Accepts an optional fax_no to be added to the fax_no array,
+always return the current fax_no array.
+
+=head2 B<e_mail( [$e_mail] )>
+
+Accessor to the e_mail attribute.
+Accepts an optional e_mail to be added to the e_mail array,
+always return the current e_mail array.
+
+=head2 B<org( [$org] )>
+
+Accessor to the org attribute.
+Accepts an optional org, always return the current org array.
+
+Points to an existing organisation object representing the entity that
+holds the resource.
+
+The 'ORG-' string followed by 2 to 4 characters, followed by up to 5 digits
+followed by a source specification.  The first digit must not be "0".
+Source specification starts with "-" followed by source name up to
+9-character length.
+
+=head2 B<nic_hdl( [$nic_hdl] )>
+
+Accessor to the nic_hdl attribute.
+Accepts an optional nic_hdl, always return the current nic_hdl.
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be added to the remarks array,
+always return the current remarks array.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+=head2 B<abuse_mailbox( [$abuse_mailbox] )>
+
+Accessor to the abuse_mailbox attribute.
+Accepts an optional abuse_mailbox value to be added to the abuse_mailbox array,
+always return the current abuse_mailbox array.
+
+=head2 B<mnt_by( [$mnt_by] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+always return the current mnt_by array.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+=cut
+
+1;
@@ -5,7 +5,7 @@ use base qw/Net::Whois::Object/;
 # http://www.ripe.net/data-tools/support/documentation/update-ref-manual#section-20
 # http://www.apnic.net/apnic-info/whois_search/using-whois/guide/person
 #
-# From :  whois -t person
+# From:  whois -t person
 # % This is the RIPE Database query service.
 # % The objects are in RPSL format.
 # %
@@ -0,0 +1,121 @@
+package Net::Whois::Object::Poem::APNIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -h whois.apnic.net -t poem
+# % [whois.apnic.net]
+# % Whois data copyright terms    http://www.apnic.net/db/dbcopyright.html
+# 
+# poem:           [mandatory]  [single]     [primary/lookup key]
+# descr:          [optional]   [multiple]   [ ]
+# form:           [mandatory]  [single]     [inverse key]
+# text:           [mandatory]  [multiple]   [ ]
+# author:         [optional]   [multiple]   [inverse key]
+# remarks:        [optional]   [multiple]   [ ]
+# notify:         [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [single]     [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+# 
+# % This query was served by the APNIC Whois Service version 1.68.5 (WHOIS1)
+
+__PACKAGE__->attributes( 'primary',   [ 'poem' ] );
+__PACKAGE__->attributes( 'mandatory', [ 'poem', 'form', 'text', 'mnt_by', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional',  [ 'descr', 'author', 'remarks', 'notify' ] );
+__PACKAGE__->attributes( 'single',    [ 'poem',  'form', 'mnt_by', 'source' ] );
+__PACKAGE__->attributes( 'multiple',  [ 'descr', 'text', 'author', 'remarks', 'notify', 'changed' ] );
+
+
+=head1 NAME
+
+Net::Whois::Object::Poem::APNIC - an object representation of the RPSL Poem block
+
+=head1 DESCRIPTION
+
+The poem object contains a poem that is submitted by a user. This object is
+included in the database to show that engineers do have a sense of humour.
+
+=head1 METHODS
+
+=head2 B<new( %options )>
+
+Constructor for the Net::Whois::Object::Poem::APNIC class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+    return $self;
+}
+
+=head2 B<descr( [$descr] )>
+
+Accessor to the descr attribute.
+Accepts an optional descr line to be added to the descr array,
+always return the current descr array.
+
+=head2 B<text( [$text] )>
+
+Accessor to the text attribute.
+Accepts an optional text line to be added to the text array,
+always return the current text array.
+
+=head2 B<admin_c( [$contact] )>
+
+Accessor to the admin_c attribute.
+Accepts an optional contact to be added to the admin_c array,
+always return the current admin_c array.
+
+=head2 B<author( [$author] )>
+
+Accessor to the author attribute.
+Accepts an optional author to be added to the author array,
+always return the current author array.
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be added to the remarks array,
+always return the current remarks array.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+=head2 B<mnt_by( [$mnt_by] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+always return the current mnt_by array.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+=head2 B<form( [$form] )>
+
+Accessor to the form attribute.
+Accepts an optional form, always return the current form.
+This attribute specifies the identifier of a registered poem type.
+
+=head2 B<poem( [$poem] )>
+
+Accessor to the poem attribute.
+Accepts an optional poem, always return the current poem.
+
+=cut
+
+1;
@@ -17,11 +17,11 @@ use base qw/Net::Whois::Object/;
 # changed:      [mandatory]     [multiple]  [ ]
 # source:       [mandatory]     [single]    [ ]
 #
-__PACKAGE__->attributes( 'primary', ['poem'] );
+__PACKAGE__->attributes( 'primary',   [ 'poem' ] );
 __PACKAGE__->attributes( 'mandatory', [ 'poem', 'form', 'text', 'author', 'admin_c', 'mnt_by', 'changed', 'source' ] );
-__PACKAGE__->attributes( 'optional', [ 'descr', 'remarks', 'notify' ] );
-__PACKAGE__->attributes( 'single',    [ 'poem',  'form',    'source' ] );
-__PACKAGE__->attributes( 'multiple',  [ 'descr', 'text',    'admin_c', 'author', 'remarks', 'notify', 'mnt_by', 'changed' ] );
+__PACKAGE__->attributes( 'optional',  [ 'descr', 'remarks', 'notify' ] );
+__PACKAGE__->attributes( 'single',    [ 'poem',  'form', 'source' ] );
+__PACKAGE__->attributes( 'multiple',  [ 'descr', 'text', 'admin_c', 'author', 'remarks', 'notify', 'mnt_by', 'changed' ] );
 
 
 =head1 NAME
@@ -0,0 +1,100 @@
+package Net::Whois::Object::PoeticForm::APNIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -h whois.apnic.net -t poetic-form
+# % [whois.apnic.net]
+# % Whois data copyright terms    http://www.apnic.net/db/dbcopyright.html
+# 
+# poetic-form:    [mandatory]  [single]     [primary/lookup key]
+# descr:          [optional]   [multiple]   [ ]
+# admin-c:        [mandatory]  [multiple]   [inverse key]
+# remarks:        [optional]   [multiple]   [ ]
+# notify:         [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+# 
+# % This query was served by the APNIC Whois Service version 1.68.5 (WHOIS1)
+
+__PACKAGE__->attributes( 'primary',   [ 'poetic_form' ] );
+__PACKAGE__->attributes( 'mandatory', [ 'poetic_form', 'admin_c', 'mnt_by', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional',  [ 'descr', 'remarks', 'notify' ] );
+__PACKAGE__->attributes( 'single',    [ 'poetic_form', 'source' ] );
+__PACKAGE__->attributes( 'multiple',  [ 'descr', 'admin_c', 'remarks', 'notify', 'mnt_by', 'changed' ] );
+
+=head1 NAME
+
+Net::Whois::Object::PoeticForm::APNIC - an object representation of the RPSL PoeticForm block
+
+=head1 DESCRIPTION
+
+The poetic_form object contains a poetic_form that is submitted by a user. This object is
+included in the database to show that engineers do have a sense of humour.
+
+=head1 METHODS
+
+=head2 B<new( %options )>
+
+Constructor for the Net::Whois::Object::PoeticForm::APNIC class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+    return $self;
+}
+
+=head2 B<poetic_form( [$poetic_form] )>
+
+Accessor to the poetic_form attribute.
+Accepts an optional poetic_form, always return the current poetic_form.
+
+=head2 B<descr( [$descr] )>
+
+Accessor to the descr attribute.
+Accepts an optional descr line to be added to the descr array,
+always return the current descr array.
+
+=head2 B<admin_c( [$contact] )>
+
+Accessor to the admin_c attribute.
+Accepts an optional contact to be added to the admin_c array,
+always return the current admin_c array.
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be added to the remarks array,
+always return the current remarks array.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+=head2 B<mnt_by( [$mnt_by] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+always return the current mnt_by array.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+=cut
+
+1;
@@ -0,0 +1,160 @@
+package Net::Whois::Object::Role::AFRINIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -t role -h whois.afrinic.net
+# % This is the AfriNIC Whois server.
+# 
+# role:           [mandatory]  [single]     [lookup key]
+# address:        [mandatory]  [multiple]   [ ]
+# phone:          [optional]   [multiple]   [ ]
+# fax-no:         [optional]   [multiple]   [ ]
+# e-mail:         [mandatory]  [multiple]   [lookup key]
+# org:            [optional]   [multiple]   [inverse key]
+# admin-c:        [mandatory]  [multiple]   [inverse key]
+# tech-c:         [mandatory]  [multiple]   [inverse key]
+# nic-hdl:        [mandatory]  [single]     [primary/look-up key]
+# remarks:        [optional]   [multiple]   [ ]
+# notify:         [optional]   [multiple]   [inverse key]
+# abuse-mailbox:  [optional]   [multiple]   [inverse key]
+# mnt-by:         [optional]   [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+
+
+__PACKAGE__->attributes( 'primary',   [ 'nic_hdl' ] );
+__PACKAGE__->attributes( 'mandatory', [ 'role', 'address', 'e_mail', 'admin_c', 'tech_c', 'nic_hdl', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional',  [ 'phone', 'fax_no', 'org', 'remarks', 'notify', 'abuse_mailbox', 'mnt_by' ] );
+__PACKAGE__->attributes( 'single',    [ 'role', 'nic_hdl', 'source' ] );
+__PACKAGE__->attributes( 'multiple',  [ 'address', 'e_mail', 'org', 'tech_c', 'admin_c', 'changed', 'phone', 'fax_no', 'trouble', 'remarks', 'notify', 'mnt_by', 'abuse_mailbox' ] );
+
+
+=head1 NAME
+
+Net::Whois::Object::Role::AFRINIC - an object representation of the RPSL Role block
+
+=head1 DESCRIPTION
+
+The role class is similar to the person class.  However, instead of
+describing a human being, it describes a role performed by one or more
+human beings.  Examples include help desks, network monitoring
+centres, system administrators, etc.  A role object is particularly
+useful since often a person performing a role may change; however the
+role itself remains. The "nic-hdl:" attributes of the person and role
+classes share the same name space. Once the object is created, the
+value of the "role:" attribute cannot be changed.
+
+=head1 METHODS
+
+=head2 B<new( %options )>
+
+Constructor for the Net::Whois::Object::Role::AFRINIC class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+    return $self;
+}
+
+=head2 B<role( [$role] )>
+
+Accessor to the role attribute.
+Accepts an optional role, always return the current role.
+
+=head2 B<address( [$address] )>
+
+Accessor to the address attribute.
+Accepts an optional address line to be added to the address array,
+always return the current address array.
+
+=head2 B<phone( [$phone] )>
+
+Accessor to the phone attribute.
+Accepts an optional phone to be added to the phone array,
+always return the current phone array.
+
+=head2 B<fax_no( [$fax_no] )>
+
+Accessor to the fax_no attribute.
+Accepts an optional fax_no to be added to the fax_no array,
+always return the current fax_no array.
+
+=head2 B<e_mail( [$e_mail] )>
+
+Accessor to the e_mail attribute.
+Accepts an optional e_mail to be added to the e_mail array,
+always return the current e_mail array.
+
+=head2 B<org( [$org] )>
+
+Accessor to the org attribute.
+Accepts an optional org, always return the current org.
+
+Points to an existing organisation object representing the entity that
+holds the resource.
+
+The 'ORG-' string followed by 2 to 4 characters, followed by up to 5 digits
+followed by a source specification.  The first digit must not be "0".
+Source specification starts with "-" followed by source name up to
+9-character length.
+
+=head2 B<trouble( [$trouble] )>
+
+Accessor to the trouble attribute.
+Accepts an optional trouble value to be added to the trouble array,
+always return the current trouble array.
+
+=head2 B<admin_c( [$contact] )>
+
+Accessor to the admin_c attribute.
+Accepts an optional contact to be added to the admin_c array,
+always return the current admin_c array.
+
+=head2 B<tech_c( [$contact] )>
+
+Accessor to the tech_c attribute.
+Accepts an optional contact to be added to the tech_c array,
+always return the current tech_c array.
+
+=head2 B<nic_hdl( [$nic_hdl] )>
+
+Accessor to the nic_hdl attribute.
+Accepts an optional nic_hdl, always return the current nic_hdl.
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be added to the remarks array,
+always return the current remarks array.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+=head2 B<mnt_by( [$mnt_by] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+always return the current mnt_by array.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+=cut
+
+1;
@@ -0,0 +1,163 @@
+package Net::Whois::Object::Role::APNIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -h whois.apnic.net -t role
+# % [whois.apnic.net]
+# % Whois data copyright terms    http://www.apnic.net/db/dbcopyright.html
+# 
+# role:           [mandatory]  [single]     [lookup key]
+# address:        [mandatory]  [multiple]   [ ]
+# country:        [mandatory]  [single]     [ ]
+# phone:          [mandatory]  [multiple]   [ ]
+# fax-no:         [optional]   [multiple]   [ ]
+# e-mail:         [mandatory]  [multiple]   [lookup key]
+# org:            [optional]   [multiple]   [inverse key]
+# admin-c:        [mandatory]  [multiple]   [inverse key]
+# tech-c:         [mandatory]  [multiple]   [inverse key]
+# nic-hdl:        [mandatory]  [single]     [primary/lookup key]
+# remarks:        [optional]   [multiple]   [ ]
+# notify:         [optional]   [multiple]   [inverse key]
+# abuse-mailbox:  [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+# 
+# % This query was served by the APNIC Whois Service version 1.68.5 (WHOIS1)
+
+__PACKAGE__->attributes( 'primary',   [ 'nic_hdl' ] );
+__PACKAGE__->attributes( 'mandatory', [ 'role', 'address', 'country', 'phone', 'e_mail', 'admin_c', 'tech_c', 'nic_hdl', 'mnt_by', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional',  [ 'fax_no', 'org', 'remarks', 'notify', 'abuse_mailbox' ] );
+__PACKAGE__->attributes( 'single',    [ 'role', 'country', 'nic_hdl', 'source' ] );
+__PACKAGE__->attributes( 'multiple',  [ 'address', 'phone', 'fax_no', 'e_mail', 'org', 'admin_c', 'tech_c', 'remarks', 'notify', 'abuse_mailbox', 'mnt_by', 'changed' ] );
+
+
+=head1 NAME
+
+Net::Whois::Object::Role::APNIC - an object representation of the RPSL Role block
+
+=head1 DESCRIPTION
+
+The role class is similar to the person class.  However, instead of
+describing a human being, it describes a role performed by one or more
+human beings.  Examples include help desks, network monitoring
+centres, system administrators, etc.  A role object is particularly
+useful since often a person performing a role may change; however the
+role itself remains. The "nic-hdl:" attributes of the person and role
+classes share the same name space. Once the object is created, the
+value of the "role:" attribute cannot be changed.
+
+=head1 METHODS
+
+=head2 B<new( %options )>
+
+Constructor for the Net::Whois::Object::Role::APNIC class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+    return $self;
+}
+
+=head2 B<role( [$role] )>
+
+Accessor to the role attribute.
+Accepts an optional role, always return the current role.
+
+=head2 B<address( [$address] )>
+
+Accessor to the address attribute.
+Accepts an optional address line to be added to the address array,
+always return the current address array.
+
+=head2 B<phone( [$phone] )>
+
+Accessor to the phone attribute.
+Accepts an optional phone to be added to the phone array,
+always return the current phone array.
+
+=head2 B<fax_no( [$fax_no] )>
+
+Accessor to the fax_no attribute.
+Accepts an optional fax_no to be added to the fax_no array,
+always return the current fax_no array.
+
+=head2 B<e_mail( [$e_mail] )>
+
+Accessor to the e_mail attribute.
+Accepts an optional e_mail to be added to the e_mail array,
+always return the current e_mail array.
+
+=head2 B<org( [$org] )>
+
+Accessor to the org attribute.
+Accepts an optional org, always return the current org.
+
+Points to an existing organisation object representing the entity that
+holds the resource.
+
+The 'ORG-' string followed by 2 to 4 characters, followed by up to 5 digits
+followed by a source specification.  The first digit must not be "0".
+Source specification starts with "-" followed by source name up to
+9-character length.
+
+=head2 B<trouble( [$trouble] )>
+
+Accessor to the trouble attribute.
+Accepts an optional trouble value to be added to the trouble array,
+always return the current trouble array.
+
+=head2 B<admin_c( [$contact] )>
+
+Accessor to the admin_c attribute.
+Accepts an optional contact to be added to the admin_c array,
+always return the current admin_c array.
+
+=head2 B<tech_c( [$contact] )>
+
+Accessor to the tech_c attribute.
+Accepts an optional contact to be added to the tech_c array,
+always return the current tech_c array.
+
+=head2 B<nic_hdl( [$nic_hdl] )>
+
+Accessor to the nic_hdl attribute.
+Accepts an optional nic_hdl, always return the current nic_hdl.
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be added to the remarks array,
+always return the current remarks array.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+=head2 B<mnt_by( [$mnt_by] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+always return the current mnt_by array.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+=cut
+
+1;
@@ -0,0 +1,220 @@
+package Net::Whois::Object::Route::AFRINIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -t route -h whois.afrinic.net
+# % This is the AfriNIC Whois server.
+# 
+# route:          [mandatory]  [single]     [primary/look-up key]
+# descr:          [mandatory]  [multiple]   [ ]
+# origin:         [mandatory]  [single]     [primary/inverse key]
+# holes:          [optional]   [multiple]   [ ]
+# org:            [optional]   [multiple]   [inverse key]
+# member-of:      [optional]   [multiple]   [ ]
+# inject:         [optional]   [multiple]   [ ]
+# aggr-mtd:       [optional]   [single]     [ ]
+# aggr-bndry:     [optional]   [single]     [ ]
+# export-comps:   [optional]   [single]     [ ]
+# components:     [optional]   [single]     [ ]
+# remarks:        [optional]   [multiple]   [ ]
+# notify:         [optional]   [multiple]   [inverse key]
+# mnt-lower:      [optional]   [multiple]   [inverse key]
+# mnt-routes:     [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+
+__PACKAGE__->attributes( 'primary',   ['route'] );
+__PACKAGE__->attributes( 'mandatory', [ 'route', 'descr', 'origin', 'mnt_by', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional', [ 'holes', 'org', 'member_of', 'inject', 'aggr_mtd', 'aggr_bndry', 'export_comps', 'components', 'remarks', 'notify', 'mnt_lower', 'mnt_routes' ] );
+__PACKAGE__->attributes( 'single', [ 'route', 'origin', 'aggr_mtd', 'aggr_bndry', 'export_comps', 'components', 'source' ] );
+__PACKAGE__->attributes( 'multiple', [ 'descr', 'holes', 'org', 'member_of', 'inject', 'remarks', 'notify', 'mnt_lower', 'mnt_routes', 'mnt_by', 'changed' ] );
+
+=head1 NAME
+
+Net::Whois::Object::Route::AFRINIC - an object representation of the RPSL Route block
+
+=head1 DESCRIPTION
+
+Route objects are used to help configure your network's routers. Route objects, 
+in combination with the aut-num and other related objects, can be used to
+describe your IPv4 routing policy in a compact form. This can help your
+network identify routing policy errors and omissions more easily than by
+reading long configuration files.
+
+
+=head1 METHODS
+
+=head2 B<new( %options )>
+
+Constructor for the Net::Whois::Object::Route::AFRINIC class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+
+    return $self;
+}
+
+=head2 B<route( [$route] )>
+
+Accessor to the route attribute.
+Accepts an optional route, always return the current route.
+
+=head2 B<descr( [$descr] )>
+
+Accessor to the descr attribute.
+Accepts an optional descr line to be added to the descr array,
+always return the current descr array.
+
+=head2 B<origin( [$origin] )>
+
+Accessor to the origin attribute.
+Accepts an optional origin, always return the current origin.
+
+=head2 B<pingable( [$pingable] )>
+
+Accessor to the pingable attribute.
+Accepts an optional pingable line to be added to the pingable array,
+always return the current pingable array.
+
+An IPv4 or an IPv6 address allowing a network operator to advertise an IP address of a node
+that should be reachable from outside networks. This node can be
+used as a destination address for diagnostic tests.
+The IP address must be within the address range of the prefix
+containing this attribute.
+
+=head2 B<ping_hdl( [$ping_hdl] )>
+
+Accessor to the ping_hdl attribute.
+Accepts an optional ping_hdl line to be added to the ping_hdl array,
+always return the current ping_hdl array.
+
+References a person or role capable of responding to queries
+concerning the IP address(es) specified in the 'pingable'
+attribute.
+
+=head2 B<holes( [$hole] )>
+
+Accessor to the holes attribute.
+Accepts an optional hole to be added to the holes array,
+always return the current holes array.
+
+=head2 B<org( [$org] )>
+
+Accessor to the org attribute.
+Accepts an optional org, always return the current org.
+
+Points to an existing organisation object representing the entity that
+holds the resource.
+
+The 'ORG-' string followed by 2 to 4 characters, followed by up to 5 digits
+followed by a source specification.  The first digit must not be "0".
+Source specification starts with "-" followed by source name up to
+9-character length.
+
+=head2 B<member_of( [$member_of] )>
+
+Accessor to the member_of attribute.
+Accepts an optional member_of value to be added to the member_of array,
+always return the current member_of array.
+
+=head2 B<inject( [$inject] )>
+
+Accessor to the inject attribute.
+Accepts an optional inject value to be added to the inject array,
+always return the current inject array.
+
+=head2 B<aggr_mtd( [$aggr_mtd] )>
+
+Accessor to the aggr_mtd attribute.
+Accepts an optional aggr_mtd value to be added to the aggr_mtd array,
+always return the current aggr_mtd.
+
+=head2 B<aggr_bndry( [$aggr_bndry] )>
+
+Accessor to the aggr_bndry attribute.
+Accepts an optional aggr_bndry value to be added to the aggr_bndry array,
+always return the current aggr_bndry.
+
+=head2 B<export_comps( [$export_comp] )>
+
+Accessor to the export_comps attribute.
+Accepts an optional export_comp value to be added the export_comps array,
+always return the current export_comps.
+
+=head2 B<components( [$component] )>
+
+Accessor to the components attribute.
+Accepts an optional component to be added to the components array,
+always return the current components.
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be added to the remarks array,
+always return the current 'remarks' array.
+
+=head2 B<cross_mnt( [$cross_mnt] )>
+
+Accessor to the cross_mnt attribute.
+Accepts an optional cross_mnt value to be added to the cross_mnt array,
+always return the current cross_mnt array.
+
+=head2 B<cross_nfy( [$cross_nfy] )>
+
+Accessor to the cross_nfy attribute.
+Accepts an optional cross_nfy value to be added to the cross_nfy array,
+always return the current cross_nfy array.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+=head2 B<mnt_lower( [$mnt_lower] )>
+
+Accessor to the mnt_lower attribute.
+Accepts an optional mnt_lower value to be added to the mnt_lower array,
+always return the current mnt_lower array.
+
+=head2 B<mnt_routes( [$mnt_route] )>
+
+Accessor to the mnt_routes attribute.
+Accepts an optional mnt_route to be added to the mnt_routes array,
+always return the current mnt_routes array.
+
+=head2 B<mnt_by( [$mnt_by] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+always return the current mnt_by array.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+=head2 B<country( [$country] )>
+
+Accessor to the country attribute.
+Accepts an optional country, always return the current country.
+Two letter ISO 3166 code of the country or economy where the admin-c is based.
+
+Please use UPPERCASE letters.
+
+=cut
+
+1;
@@ -0,0 +1,224 @@
+package Net::Whois::Object::Route::APNIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -h whois.apnic.net -t route
+# % [whois.apnic.net]
+# % Whois data copyright terms    http://www.apnic.net/db/dbcopyright.html
+# 
+# route:          [mandatory]  [single]     [primary/lookup key]
+# descr:          [mandatory]  [multiple]   [ ]
+# origin:         [mandatory]  [single]     [primary/inverse key]
+# holes:          [optional]   [multiple]   [ ]
+# country:        [optional]   [single]     [ ]
+# org:            [optional]   [multiple]   [inverse key]
+# member-of:      [optional]   [multiple]   [inverse key]
+# inject:         [optional]   [multiple]   [ ]
+# aggr-mtd:       [optional]   [single]     [ ]
+# aggr-bndry:     [optional]   [single]     [ ]
+# export-comps:   [optional]   [single]     [ ]
+# components:     [optional]   [single]     [ ]
+# remarks:        [optional]   [multiple]   [ ]
+# notify:         [optional]   [multiple]   [inverse key]
+# mnt-lower:      [optional]   [multiple]   [inverse key]
+# mnt-routes:     [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+# 
+# % This query was served by the APNIC Whois Service version 1.68.5 (WHOIS3)
+
+__PACKAGE__->attributes( 'primary',   [ 'route' ] );
+__PACKAGE__->attributes( 'mandatory', [ 'route', 'descr', 'origin', 'mnt_by', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional',  [ 'holes', 'country', 'org', 'member_of', 'inject', 'aggr_mtd', 'aggr_bndry', 'export_comps', 'components', 'remarks', 'notify', 'mnt_lower', 'mnt_routes' ] );
+__PACKAGE__->attributes( 'single',    [ 'route', 'origin', 'country', 'aggr_mtd', 'aggr_bndry', 'export_comps', 'components', 'source' ] );
+__PACKAGE__->attributes( 'multiple',  [ 'descr', 'holes', 'org', 'member_of', 'inject', 'remarks', 'notify', 'mnt_lower', 'mnt_routes', 'mnt_by', 'changed' ] );
+
+=head1 NAME
+
+Net::Whois::Object::Route::APNIC - an object representation of the RPSL Route block
+
+=head1 DESCRIPTION
+
+Route objects are used to help configure your network's routers. Route objects, 
+in combination with the aut-num and other related objects, can be used to
+describe your IPv4 routing policy in a compact form. This can help your
+network identify routing policy errors and omissions more easily than by
+reading long configuration files.
+
+
+=head1 METHODS
+
+=head2 B<new( %options )>
+
+Constructor for the Net::Whois::Object::Route::APNIC class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+
+    return $self;
+}
+
+=head2 B<route( [$route] )>
+
+Accessor to the route attribute.
+Accepts an optional route, always return the current route.
+
+=head2 B<descr( [$descr] )>
+
+Accessor to the descr attribute.
+Accepts an optional descr line to be added to the descr array,
+always return the current descr array.
+
+=head2 B<origin( [$origin] )>
+
+Accessor to the origin attribute.
+Accepts an optional origin, always return the current origin.
+
+=head2 B<pingable( [$pingable] )>
+
+Accessor to the pingable attribute.
+Accepts an optional pingable line to be added to the pingable array,
+always return the current pingable array.
+
+An IPv4 or an IPv6 address allowing a network operator to advertise an IP address of a node
+that should be reachable from outside networks. This node can be
+used as a destination address for diagnostic tests.
+The IP address must be within the address range of the prefix
+containing this attribute.
+
+=head2 B<ping_hdl( [$ping_hdl] )>
+
+Accessor to the ping_hdl attribute.
+Accepts an optional ping_hdl line to be added to the ping_hdl array,
+always return the current ping_hdl array.
+
+References a person or role capable of responding to queries
+concerning the IP address(es) specified in the 'pingable'
+attribute.
+
+=head2 B<holes( [$hole] )>
+
+Accessor to the holes attribute.
+Accepts an optional hole to be added to the holes array,
+always return the current holes array.
+
+=head2 B<org( [$org] )>
+
+Accessor to the org attribute.
+Accepts an optional org, always return the current org.
+
+Points to an existing organisation object representing the entity that
+holds the resource.
+
+The 'ORG-' string followed by 2 to 4 characters, followed by up to 5 digits
+followed by a source specification.  The first digit must not be "0".
+Source specification starts with "-" followed by source name up to
+9-character length.
+
+=head2 B<member_of( [$member_of] )>
+
+Accessor to the member_of attribute.
+Accepts an optional member_of value to be added to the member_of array,
+always return the current member_of array.
+
+=head2 B<inject( [$inject] )>
+
+Accessor to the inject attribute.
+Accepts an optional inject value to be added to the inject array,
+always return the current inject array.
+
+=head2 B<aggr_mtd( [$aggr_mtd] )>
+
+Accessor to the aggr_mtd attribute.
+Accepts an optional aggr_mtd value to be added to the aggr_mtd array,
+always return the current aggr_mtd.
+
+=head2 B<aggr_bndry( [$aggr_bndry] )>
+
+Accessor to the aggr_bndry attribute.
+Accepts an optional aggr_bndry value to be added to the aggr_bndry array,
+always return the current aggr_bndry.
+
+=head2 B<export_comps( [$export_comp] )>
+
+Accessor to the export_comps attribute.
+Accepts an optional export_comp value to be added the export_comps array,
+always return the current export_comps.
+
+=head2 B<components( [$component] )>
+
+Accessor to the components attribute.
+Accepts an optional component to be added to the components array,
+always return the current components.
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be added to the remarks array,
+always return the current 'remarks' array.
+
+=head2 B<cross_mnt( [$cross_mnt] )>
+
+Accessor to the cross_mnt attribute.
+Accepts an optional cross_mnt value to be added to the cross_mnt array,
+always return the current cross_mnt array.
+
+=head2 B<cross_nfy( [$cross_nfy] )>
+
+Accessor to the cross_nfy attribute.
+Accepts an optional cross_nfy value to be added to the cross_nfy array,
+always return the current cross_nfy array.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+=head2 B<mnt_lower( [$mnt_lower] )>
+
+Accessor to the mnt_lower attribute.
+Accepts an optional mnt_lower value to be added to the mnt_lower array,
+always return the current mnt_lower array.
+
+=head2 B<mnt_routes( [$mnt_route] )>
+
+Accessor to the mnt_routes attribute.
+Accepts an optional mnt_route to be added to the mnt_routes array,
+always return the current mnt_routes array.
+
+=head2 B<mnt_by( [$mnt_by] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+always return the current mnt_by array.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+=head2 B<country( [$country] )>
+
+Accessor to the country attribute.
+Accepts an optional country, always return the current country.
+Two letter ISO 3166 code of the country or economy where the admin-c is based.
+
+Please use UPPERCASE letters.
+
+=cut
+
+1;
@@ -5,7 +5,7 @@ use base qw/Net::Whois::Object/;
 # http://www.ripe.net/data-tools/support/documentation/update-ref-manual#section-25
 # http://www.apnic.net/apnic-info/whois_search/using-whois/guide/route
 #
-# From : whois -t route
+# From: whois -t route
 # % This is the RIPE Database query service.
 # % The objects are in RPSL format.
 # %
@@ -0,0 +1,206 @@
+package Net::Whois::Object::Route6::AFRINIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -t route6 -h whois.afrinic.net
+# % This is the AfriNIC Whois server.
+# 
+# route6:         [mandatory]  [single]     [primary/look-up key]
+# descr:          [mandatory]  [multiple]   [ ]
+# origin:         [mandatory]  [single]     [primary/inverse key]
+# holes:          [optional]   [multiple]   [ ]
+# org:            [optional]   [multiple]   [inverse key]
+# member-of:      [optional]   [multiple]   [ ]
+# inject:         [optional]   [multiple]   [ ]
+# aggr-mtd:       [optional]   [single]     [ ]
+# aggr-bndry:     [optional]   [single]     [ ]
+# export-comps:   [optional]   [single]     [ ]
+# components:     [optional]   [single]     [ ]
+# remarks:        [optional]   [multiple]   [ ]
+# notify:         [optional]   [multiple]   [inverse key]
+# mnt-lower:      [optional]   [multiple]   [inverse key]
+# mnt-routes:     [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+
+__PACKAGE__->attributes( 'primary',   ['route6'] );
+__PACKAGE__->attributes( 'mandatory', [ 'route6', 'descr', 'origin', 'mnt_by', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional', [ 'holes', 'org', 'member_of', 'inject', 'aggr_mtd', 'aggr_bndry', 'export_comps', 'components', 'remarks', 'notify', 'mnt_lower', 'mnt_routes' ] );
+__PACKAGE__->attributes( 'single', [ 'route6', 'origin', 'aggr_mtd', 'aggr_bndry', 'export_comps', 'components', 'source' ] );
+__PACKAGE__->attributes( 'multiple', [ 'descr', 'holes', 'org', 'member_of', 'inject', 'remarks', 'notify', 'mnt_lower', 'mnt_routes', 'mnt_by', 'changed' ] );
+
+=head1 NAME
+
+Net::Whois::Object::Route6::AFRINIC - an object representation of the RPSL Route6 block
+
+=head1 DESCRIPTION
+
+Route6 objects are used to help configure your network's routers. Route6 objects,
+in combination with the aut-num and other related objects, can be used to
+describe your IPv6 routing policy in a compact form. This can help your
+network identify routing policy errors and omissions more easily than by
+reading long configuration files.
+
+=head1 METHODS
+
+=head2 B<new( %options )>
+
+Constructor for the Net::Whois::Object::Route6::AFRINIC class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+    return $self;
+}
+
+=head2 B<route6( [$route6] )>
+
+Accessor to the route6 attribute.
+Accepts an optional route6, always return the current route.
+
+=head2 B<descr( [$descr] )>
+
+Accessor to the descr attribute.
+Accepts an optional descr line to be added to the descr array,
+always return the current descr array.
+
+=head2 B<origin( [$origin] )>
+
+Accessor to the origin attribute.
+Accepts an optional origin, always return the current origin.
+
+=head2 B<pingable( [$pingable] )>
+
+Accessor to the pingable attribute.
+Accepts an optional pingable line to be added to the pingable array,
+always return the current pingable array.
+
+An IPv4 or an IPv6 address allowing a network operator to advertise an IP address of a node
+that should be reachable from outside networks. This node can be
+used as a destination address for diagnostic tests.
+The IP address must be within the address range of the prefix
+containing this attribute.
+
+=head2 B<ping_hdl( [$ping_hdl] )>
+
+Accessor to the ping_hdl attribute.
+Accepts an optional ping_hdl line to be added to the ping_hdl array,
+always return the current ping_hdl array.
+
+References a person or role capable of responding to queries
+concerning the IP address(es) specified in the 'pingable'
+attribute.
+
+=head2 B<holes( [$hole] )>
+
+Accessor to the holes attribute.
+Accepts an optional hole to be added to the holes array,
+always return the current holes array.
+
+=head2 B<org( [$org] )>
+
+Accessor to the org attribute.
+Accepts an optional org, always return the current org.
+
+Points to an existing organisation object representing the entity that
+holds the resource.
+
+The 'ORG-' string followed by 2 to 4 characters, followed by up to 5 digits
+followed by a source specification.  The first digit must not be "0".
+Source specification starts with "-" followed by source name up to
+9-character length.
+
+=head2 B<member_of( [$member_of] )>
+
+Accessor to the member_of attribute.
+Accepts an optional member_of value to be added to the member_of array,
+always return the current member_of array.
+
+=head2 B<inject( [$inject] )>
+
+Accessor to the inject attribute.
+Accepts an optional inject value to be added to the inject array,
+always return the current inject array.
+
+=head2 B<aggr_mtd( [$aggr_mtd] )>
+
+Accessor to the aggr_mtd attribute.
+Accepts an optional aggr_mtd value to be added to the aggr_mtd array,
+always return the current aggr_mtd.
+
+=head2 B<aggr_bndry( [$aggr_bndry] )>
+
+Accessor to the aggr_bndry attribute.
+Accepts an optional aggr_bndry value to be added to the aggr_bndry array,
+always return the current aggr_bndry.
+
+=head2 B<export_comps( [$export_comp] )>
+
+Accessor to the export_comps attribute.
+Accepts an optional export_comp value to be added the export_comps array,
+always return the current export_comps.
+
+=head2 B<components( [$component] )>
+
+Accessor to the components attribute.
+Accepts an optional component to be added to the components array,
+always return the current components.
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be added to the remarks array,
+always return the current 'remarks' array.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+=head2 B<mnt_lower( [$mnt_lower] )>
+
+Accessor to the mnt_lower attribute.
+Accepts an optional mnt_lower value to be added to the mnt_lower array,
+always return the current mnt_lower array.
+
+=head2 B<mnt_routes( [$mnt_route] )>
+
+Accessor to the mnt_routes attribute.
+Accepts an optional mnt_route to be added to the mnt_routes array,
+always return the current mnt_routes array.
+
+=head2 B<mnt_by( [$mnt_by] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+always return the current mnt_by array.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+=head2 B<country( [$country] )>
+
+Accessor to the country attribute.
+Accepts an optional country, always return the current country.
+Two letter ISO 3166 code of the country or economy where the admin-c is based.
+
+Please use UPPERCASE letters.
+
+=cut
+
+1;
@@ -0,0 +1,210 @@
+package Net::Whois::Object::Route6::APNIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -h whois.apnic.net -t route6
+# % [whois.apnic.net]
+# % Whois data copyright terms    http://www.apnic.net/db/dbcopyright.html
+# 
+# route6:         [mandatory]  [single]     [primary/lookup key]
+# descr:          [mandatory]  [multiple]   [ ]
+# origin:         [mandatory]  [single]     [primary/inverse key]
+# country:        [optional]   [single]     [ ]
+# holes:          [optional]   [multiple]   [ ]
+# org:            [optional]   [multiple]   [inverse key]
+# member-of:      [optional]   [multiple]   [inverse key]
+# inject:         [optional]   [multiple]   [ ]
+# aggr-mtd:       [optional]   [single]     [ ]
+# aggr-bndry:     [optional]   [single]     [ ]
+# export-comps:   [optional]   [single]     [ ]
+# components:     [optional]   [single]     [ ]
+# remarks:        [optional]   [multiple]   [ ]
+# notify:         [optional]   [multiple]   [inverse key]
+# mnt-lower:      [optional]   [multiple]   [inverse key]
+# mnt-routes:     [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+# 
+# % This query was served by the APNIC Whois Service version 1.68.5 (WHOIS2)
+
+__PACKAGE__->attributes( 'primary',   [ 'route6' ] );
+__PACKAGE__->attributes( 'mandatory', [ 'route6', 'descr', 'origin', 'mnt_by', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional',  [ 'country', 'holes', 'org', 'member_of', 'inject', 'aggr_mtd', 'aggr_bndry', 'export_comps', 'components', 'remarks', 'notify', 'mnt_lower', 'mnt_routes' ] );
+__PACKAGE__->attributes( 'single',    [ 'route6', 'origin', 'country', 'aggr_mtd', 'aggr_bndry', 'export_comps', 'components', 'source' ] );
+__PACKAGE__->attributes( 'multiple',  [ 'descr', 'holes', 'org', 'member_of', 'inject', 'remarks', 'notify', 'mnt_lower', 'mnt_routes', 'mnt_by', 'changed' ] );
+
+=head1 NAME
+
+Net::Whois::Object::Route6::APNIC - an object representation of the RPSL Route6 block
+
+=head1 DESCRIPTION
+
+Route6 objects are used to help configure your network's routers. Route6 objects,
+in combination with the aut-num and other related objects, can be used to
+describe your IPv6 routing policy in a compact form. This can help your
+network identify routing policy errors and omissions more easily than by
+reading long configuration files.
+
+=head1 METHODS
+
+=head2 B<new( %options )>
+
+Constructor for the Net::Whois::Object::Route6::APNIC class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+    return $self;
+}
+
+=head2 B<route6( [$route6] )>
+
+Accessor to the route6 attribute.
+Accepts an optional route6, always return the current route.
+
+=head2 B<descr( [$descr] )>
+
+Accessor to the descr attribute.
+Accepts an optional descr line to be added to the descr array,
+always return the current descr array.
+
+=head2 B<origin( [$origin] )>
+
+Accessor to the origin attribute.
+Accepts an optional origin, always return the current origin.
+
+=head2 B<pingable( [$pingable] )>
+
+Accessor to the pingable attribute.
+Accepts an optional pingable line to be added to the pingable array,
+always return the current pingable array.
+
+An IPv4 or an IPv6 address allowing a network operator to advertise an IP address of a node
+that should be reachable from outside networks. This node can be
+used as a destination address for diagnostic tests.
+The IP address must be within the address range of the prefix
+containing this attribute.
+
+=head2 B<ping_hdl( [$ping_hdl] )>
+
+Accessor to the ping_hdl attribute.
+Accepts an optional ping_hdl line to be added to the ping_hdl array,
+always return the current ping_hdl array.
+
+References a person or role capable of responding to queries
+concerning the IP address(es) specified in the 'pingable'
+attribute.
+
+=head2 B<holes( [$hole] )>
+
+Accessor to the holes attribute.
+Accepts an optional hole to be added to the holes array,
+always return the current holes array.
+
+=head2 B<org( [$org] )>
+
+Accessor to the org attribute.
+Accepts an optional org, always return the current org.
+
+Points to an existing organisation object representing the entity that
+holds the resource.
+
+The 'ORG-' string followed by 2 to 4 characters, followed by up to 5 digits
+followed by a source specification.  The first digit must not be "0".
+Source specification starts with "-" followed by source name up to
+9-character length.
+
+=head2 B<member_of( [$member_of] )>
+
+Accessor to the member_of attribute.
+Accepts an optional member_of value to be added to the member_of array,
+always return the current member_of array.
+
+=head2 B<inject( [$inject] )>
+
+Accessor to the inject attribute.
+Accepts an optional inject value to be added to the inject array,
+always return the current inject array.
+
+=head2 B<aggr_mtd( [$aggr_mtd] )>
+
+Accessor to the aggr_mtd attribute.
+Accepts an optional aggr_mtd value to be added to the aggr_mtd array,
+always return the current aggr_mtd.
+
+=head2 B<aggr_bndry( [$aggr_bndry] )>
+
+Accessor to the aggr_bndry attribute.
+Accepts an optional aggr_bndry value to be added to the aggr_bndry array,
+always return the current aggr_bndry.
+
+=head2 B<export_comps( [$export_comp] )>
+
+Accessor to the export_comps attribute.
+Accepts an optional export_comp value to be added the export_comps array,
+always return the current export_comps.
+
+=head2 B<components( [$component] )>
+
+Accessor to the components attribute.
+Accepts an optional component to be added to the components array,
+always return the current components.
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be added to the remarks array,
+always return the current 'remarks' array.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+=head2 B<mnt_lower( [$mnt_lower] )>
+
+Accessor to the mnt_lower attribute.
+Accepts an optional mnt_lower value to be added to the mnt_lower array,
+always return the current mnt_lower array.
+
+=head2 B<mnt_routes( [$mnt_route] )>
+
+Accessor to the mnt_routes attribute.
+Accepts an optional mnt_route to be added to the mnt_routes array,
+always return the current mnt_routes array.
+
+=head2 B<mnt_by( [$mnt_by] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+always return the current mnt_by array.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+=head2 B<country( [$country] )>
+
+Accessor to the country attribute.
+Accepts an optional country, always return the current country.
+Two letter ISO 3166 code of the country or economy where the admin-c is based.
+
+Please use UPPERCASE letters.
+
+=cut
+
+1;
@@ -0,0 +1,152 @@
+package Net::Whois::Object::RouteSet::AFRINIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -t route-set -h whois.afrinic.net
+# % This is the AfriNIC Whois server.
+# 
+# route-set:      [mandatory]  [single]     [primary/look-up key]
+# descr:          [mandatory]  [multiple]   [ ]
+# members:        [optional]   [multiple]   [ ]
+# mp-members:     [optional]   [multiple]   [ ]
+# mbrs-by-ref:    [optional]   [multiple]   [inverse key]
+# remarks:        [optional]   [multiple]   [ ]
+# org:            [optional]   [multiple]   [inverse key]
+# tech-c:         [mandatory]  [multiple]   [inverse key]
+# admin-c:        [mandatory]  [multiple]   [inverse key]
+# notify:         [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [multiple]   [inverse key]
+# mnt-lower:      [optional]   [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+
+__PACKAGE__->attributes( 'primary', ['route_set'] );
+__PACKAGE__->attributes( 'mandatory', [ 'route_set', 'descr', 'tech_c', 'admin_c', 'mnt_by', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional', [ 'members', 'mp_members', 'mbrs_by_ref', 'remarks', 'org', 'notify', 'mnt_lower' ] );
+__PACKAGE__->attributes( 'single', [ 'route_set', 'source' ] );
+__PACKAGE__->attributes( 'multiple', [ 'descr', 'members', 'mp_members', 'mbrs_by_ref', 'remarks', 'org', 'tech_c', 'admin_c', 'notify', 'mnt_by', 'mnt_lower', 'changed' ] );
+
+=head1 NAME
+
+Net::Whois::Object::RouteSet::AFRINIC - an object representation of the RPSL RouteSet block
+
+=head1 DESCRIPTION
+
+A route-set object defines a set of routes that can be represented by
+route objects or by address prefixes. In the first case, the set is
+populated by means of the "mbrs-by-ref:" attribute, in the latter, the
+members of the set are explicitly listed in the "members:"
+attribute. The "members:" attribute is a list of address prefixes or
+other route-set names.  Note that the route-set class is a set of
+route prefixes, not of database route objects.
+
+=head1 METHODS
+
+=head2 B<new( %options )>
+
+Constructor for the Net::Whois::Object::RouteSet::AFRINIC class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+
+    return $self;
+}
+
+=head2 B<route_set( [$route_set] )>
+
+Accessor to the route_set attribute.
+Accepts an optional route_set, always return the current route_set.
+
+=head2 B<descr( [$descr] )>
+
+Accessor to the descr attribute.
+Accepts an optional descr line to be added to the descr array,
+always return the current descr array.
+
+=head2 B<members( [$members] )>
+
+Accessor to the members attribute.
+Accepts an optional members value to be added to the members array,
+always return the current members array.
+
+=head2 B<mbrs_by_ref( [$mbrs_by_ref] )>
+
+Accessor to the mbrs_by_ref attribute.
+Accepts an optional mbrs_by_ref to be added to the mbrs_by_ref array,
+        always return the current 'mbrs_by_ref' array.
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be added to the remarks array,
+always return the current remarks array.
+
+=head2 B<org( [$org] )>
+
+Accessor to the org attribute.
+Accepts an optional org, always return the current org.
+
+Points to an existing organisation object representing the entity that
+holds the resource.
+
+The 'ORG-' string followed by 2 to 4 characters, followed by up to 5 digits
+followed by a source specification.  The first digit must not be "0".
+Source specification starts with "-" followed by source name up to
+9-character length.
+
+=head2 B<tech_c( [$contact] )>
+
+Accessor to the tech_c attribute.
+Accepts an optional contact to be added to the tech_c array,
+always return the current tech_c array.
+
+=head2 B<admin_c( [$contact] )>
+
+Accessor to the admin_c attribute.
+Accepts an optional contact to be added to the admin_c array,
+always return the current admin_c array.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+=head2 B<mnt_by( [$mnt_by] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+always return the current mnt_by array.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+=head2 B<mnt_lower( [$mnt_lower] )>
+
+Accessor to the mnt_lower attribute.
+Accepts an optional mnt_lower value to be added to the mnt_lower array,
+always return the current mnt_lower array.
+
+=head2 B<mp_members( [$mp_member] )>
+
+Accessor to the mp_members attribute.
+Accepts an optional mp_member to be added to the mp_members array,
+always return the current mp_members array.
+
+=cut
+
+1;
@@ -0,0 +1,155 @@
+package Net::Whois::Object::RouteSet::APNIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -h whois.apnic.net -t route-set
+# % [whois.apnic.net]
+# % Whois data copyright terms    http://www.apnic.net/db/dbcopyright.html
+# 
+# route-set:      [mandatory]  [single]     [primary/lookup key]
+# descr:          [mandatory]  [multiple]   [ ]
+# members:        [optional]   [multiple]   [ ]
+# mp-members:     [optional]   [multiple]   [ ]
+# mbrs-by-ref:    [optional]   [multiple]   [inverse key]
+# remarks:        [optional]   [multiple]   [ ]
+# org:            [optional]   [multiple]   [inverse key]
+# tech-c:         [mandatory]  [multiple]   [inverse key]
+# admin-c:        [mandatory]  [multiple]   [inverse key]
+# notify:         [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [multiple]   [inverse key]
+# mnt-lower:      [optional]   [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+# 
+# % This query was served by the APNIC Whois Service version 1.68.5 (WHOIS2)
+ 
+__PACKAGE__->attributes( 'primary',   [ 'route_set' ] );
+__PACKAGE__->attributes( 'mandatory', [ 'route_set', 'descr', 'tech_c', 'admin_c', 'mnt_by', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional',  [ 'members', 'mp_members', 'mbrs_by_ref', 'remarks', 'org', 'notify', 'mnt_lower' ] );
+__PACKAGE__->attributes( 'single',    [ 'route_set', 'source' ] );
+__PACKAGE__->attributes( 'multiple',  [ 'descr', 'members', 'mp_members', 'mbrs_by_ref', 'remarks', 'org', 'tech_c', 'admin_c', 'notify', 'mnt_by', 'mnt_lower', 'changed' ] );
+
+=head1 NAME
+
+Net::Whois::Object::RouteSet::APNIC - an object representation of the RPSL RouteSet block
+
+=head1 DESCRIPTION
+
+A route-set object defines a set of routes that can be represented by
+route objects or by address prefixes. In the first case, the set is
+populated by means of the "mbrs-by-ref:" attribute, in the latter, the
+members of the set are explicitly listed in the "members:"
+attribute. The "members:" attribute is a list of address prefixes or
+other route-set names.  Note that the route-set class is a set of
+route prefixes, not of database route objects.
+
+=head1 METHODS
+
+=head2 B<new( %options )>
+
+Constructor for the Net::Whois::Object::RouteSet::APNIC class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+
+    return $self;
+}
+
+=head2 B<route_set( [$route_set] )>
+
+Accessor to the route_set attribute.
+Accepts an optional route_set, always return the current route_set.
+
+=head2 B<descr( [$descr] )>
+
+Accessor to the descr attribute.
+Accepts an optional descr line to be added to the descr array,
+always return the current descr array.
+
+=head2 B<members( [$members] )>
+
+Accessor to the members attribute.
+Accepts an optional members value to be added to the members array,
+always return the current members array.
+
+=head2 B<mbrs_by_ref( [$mbrs_by_ref] )>
+
+Accessor to the mbrs_by_ref attribute.
+Accepts an optional mbrs_by_ref to be added to the mbrs_by_ref array,
+        always return the current 'mbrs_by_ref' array.
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be added to the remarks array,
+always return the current remarks array.
+
+=head2 B<org( [$org] )>
+
+Accessor to the org attribute.
+Accepts an optional org, always return the current org.
+
+Points to an existing organisation object representing the entity that
+holds the resource.
+
+The 'ORG-' string followed by 2 to 4 characters, followed by up to 5 digits
+followed by a source specification.  The first digit must not be "0".
+Source specification starts with "-" followed by source name up to
+9-character length.
+
+=head2 B<tech_c( [$contact] )>
+
+Accessor to the tech_c attribute.
+Accepts an optional contact to be added to the tech_c array,
+always return the current tech_c array.
+
+=head2 B<admin_c( [$contact] )>
+
+Accessor to the admin_c attribute.
+Accepts an optional contact to be added to the admin_c array,
+always return the current admin_c array.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+=head2 B<mnt_by( [$mnt_by] )>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+always return the current mnt_by array.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+=head2 B<mnt_lower( [$mnt_lower] )>
+
+Accessor to the mnt_lower attribute.
+Accepts an optional mnt_lower value to be added to the mnt_lower array,
+always return the current mnt_lower array.
+
+=head2 B<mp_members( [$mp_member] )>
+
+Accessor to the mp_members attribute.
+Accepts an optional mp_member to be added to the mp_members array,
+always return the current mp_members array.
+
+=cut
+
+1;
@@ -5,7 +5,7 @@ use base qw/Net::Whois::Object/;
 # http://www.ripe.net/data-tools/support/documentation/update-ref-manual#section-26
 # http://www.apnic.net/apnic-info/whois_search/using-whois/guide/route-set
 #
-# From : whois -t route-set
+# From: whois -t route-set
 # % This is the RIPE Database query service.
 # % The objects are in RPSL format.
 # %
@@ -0,0 +1,154 @@
+package Net::Whois::Object::RtrSet::AFRINIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -t rtr-set -h whois.afrinic.net
+# % This is the AfriNIC Whois server.
+# 
+# rtr-set:        [mandatory]  [single]     [primary/look-up key]
+# descr:          [mandatory]  [multiple]   [ ]
+# members:        [optional]   [multiple]   [ ]
+# mp-members:     [optional]   [multiple]   [ ]
+# mbrs-by-ref:    [optional]   [multiple]   [inverse key]
+# remarks:        [optional]   [multiple]   [ ]
+# org:            [optional]   [multiple]   [inverse key]
+# tech-c:         [mandatory]  [multiple]   [inverse key]
+# admin-c:        [mandatory]  [multiple]   [inverse key]
+# notify:         [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [multiple]   [inverse key]
+# mnt-lower:      [optional]   [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+
+__PACKAGE__->attributes( 'primary', ['rtr_set'] );
+__PACKAGE__->attributes( 'mandatory', [ 'rtr_set', 'descr', 'tech_c', 'admin_c', 'mnt_by', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional', [ 'members', 'mp_members', 'mbrs_by_ref', 'remarks', 'org', 'notify', 'mnt_lower' ] );
+__PACKAGE__->attributes( 'single', [ 'rtr_set', 'source' ] );
+__PACKAGE__->attributes( 'multiple', [ 'descr', 'members', 'mp_members', 'mbrs_by_ref', 'remarks', 'org', 'tech_c', 'admin_c', 'notify', 'mnt_by', 'mnt_lower', 'changed' ] );
+
+=head1 NAME
+
+Net::Whois::Object::RtrSet::AFRINIC - an object representation of the RPSL RtrSet block
+
+=head1 DESCRIPTION
+
+A rtr-set object defines a set of routers. A set may be described by
+the "members:" attribute, which is a list of inet-rtr names, IPv4
+addresses or other rtr-set names. A set may also be populated by means
+of the "mbrs-by-ref:" attribute, in which case it is represented by
+inet-rtr objects.
+
+=head1 METHODS
+
+=head2 B<new( %options )>
+
+Constructor for the Net::Whois::Object::RtrSet::AFRINIC class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+    return $self;
+}
+
+=head2 B<rtr_set( [$rtr_set] )>
+
+Accessor to the rtr_set attribute.
+Accepts an optional rtr_set, always return the current rtr_set.
+
+=head2 B<descr( [$descr] )>
+
+Accessor to the descr attribute.
+Accepts an optional descr line to be added to the descr array,
+always return the current descr array.
+
+=head2 B<members( [$member] )>
+
+Accessor to the members attribute.
+Accepts an optional member to be added to the members array,
+always return the current members array.
+
+=head2 B<mbrs_by_ref( [$mbrs_by_ref] )>
+
+Accessor to the mbrs_by_ref attribute.
+Accepts an optional mbrs_by_ref value to be added to the mbrs_by_ref array,
+always return the current mbrs_by_ref array.
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be added to the remarks array,
+always return the current remarks array.
+
+=head2 B<org( [$org] )>
+
+Accessor to the org attribute.
+Accepts an optional org, always return the current org.
+
+Points to an existing organisation object representing the entity that
+holds the resource.
+
+The 'ORG-' string followed by 2 to 4 characters, followed by up to 5 digits
+followed by a source specification.  The first digit must not be "0".
+Source specification starts with "-" followed by source name up to
+9-character length.
+
+=head2 B<tech_c( [$contact] )>
+
+Accessor to the tech_c attribute.
+Accepts an optional contact to be added to the tech_c array,
+always return the current tech_c array.
+
+=head2 B<admin_c( [$contact] )>
+
+Accessor to the admin_c attribute.
+Accepts an optional contact to be added to the admin_c array,
+always return the current admin_c array.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+=head2 B<mnt_by( [$mnt_by])>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+always return the current mnt_by array.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+=head2 B<mp_members( [$mp_member] )>
+
+Accessor to the mp_members attribute.
+Accepts an optional mp_member to be added to the mp_members array,
+always return the current mp_members array.
+
+This attribute performs the same function as the members attribute above.
+The difference is that mp-members allows both IPv4 and IPv6 address families
+to be specified.
+
+Explicitly lists IPv4 or IPv6 'members' of the rtr-set can be:
+
+    * inet-rtr objects
+    * other rtr-set objects
+    * ipv4 address
+    * ipv6 address
+
+=cut
+
+1;
@@ -0,0 +1,157 @@
+package Net::Whois::Object::RtrSet::APNIC;
+
+use base qw/Net::Whois::Object/;
+
+# whois -h whois.apnic.net -t rtr-set
+# % [whois.apnic.net]
+# % Whois data copyright terms    http://www.apnic.net/db/dbcopyright.html
+# 
+# rtr-set:        [mandatory]  [single]     [primary/lookup key]
+# descr:          [mandatory]  [multiple]   [ ]
+# members:        [optional]   [multiple]   [ ]
+# mp-members:     [optional]   [multiple]   [ ]
+# mbrs-by-ref:    [optional]   [multiple]   [inverse key]
+# remarks:        [optional]   [multiple]   [ ]
+# org:            [optional]   [multiple]   [inverse key]
+# tech-c:         [mandatory]  [multiple]   [inverse key]
+# admin-c:        [mandatory]  [multiple]   [inverse key]
+# notify:         [optional]   [multiple]   [inverse key]
+# mnt-by:         [mandatory]  [multiple]   [inverse key]
+# mnt-lower:      [optional]   [multiple]   [inverse key]
+# changed:        [mandatory]  [multiple]   [ ]
+# source:         [mandatory]  [single]     [ ]
+# 
+# % This query was served by the APNIC Whois Service version 1.68.5 (WHOIS4)
+
+__PACKAGE__->attributes( 'primary',   [ 'rtr_set' ] );
+__PACKAGE__->attributes( 'mandatory', [ 'rtr_set', 'descr', 'tech_c', 'admin_c', 'mnt_by', 'changed', 'source' ] );
+__PACKAGE__->attributes( 'optional',  [ 'members', 'mp_members', 'mbrs_by_ref', 'remarks', 'org', 'notify', 'mnt_lower' ] );
+__PACKAGE__->attributes( 'single',    [ 'rtr_set', 'source' ] );
+__PACKAGE__->attributes( 'multiple',  [ 'descr', 'members', 'mp_members', 'mbrs_by_ref', 'remarks', 'org', 'tech_c', 'admin_c', 'notify', 'mnt_by', 'mnt_lower', 'changed' ] );
+
+=head1 NAME
+
+Net::Whois::Object::RtrSet::APNIC - an object representation of the RPSL RtrSet block
+
+=head1 DESCRIPTION
+
+A rtr-set object defines a set of routers. A set may be described by
+the "members:" attribute, which is a list of inet-rtr names, IPv4
+addresses or other rtr-set names. A set may also be populated by means
+of the "mbrs-by-ref:" attribute, in which case it is represented by
+inet-rtr objects.
+
+=head1 METHODS
+
+=head2 B<new( %options )>
+
+Constructor for the Net::Whois::Object::RtrSet::APNIC class
+
+=cut
+
+sub new {
+    my ( $class, @options ) = @_;
+
+    my $self = bless {}, $class;
+    $self->_init(@options);
+
+    return $self;
+}
+
+=head2 B<rtr_set( [$rtr_set] )>
+
+Accessor to the rtr_set attribute.
+Accepts an optional rtr_set, always return the current rtr_set.
+
+=head2 B<descr( [$descr] )>
+
+Accessor to the descr attribute.
+Accepts an optional descr line to be added to the descr array,
+always return the current descr array.
+
+=head2 B<members( [$member] )>
+
+Accessor to the members attribute.
+Accepts an optional member to be added to the members array,
+always return the current members array.
+
+=head2 B<mbrs_by_ref( [$mbrs_by_ref] )>
+
+Accessor to the mbrs_by_ref attribute.
+Accepts an optional mbrs_by_ref value to be added to the mbrs_by_ref array,
+always return the current mbrs_by_ref array.
+
+=head2 B<remarks( [$remark] )>
+
+Accessor to the remarks attribute.
+Accepts an optional remark to be added to the remarks array,
+always return the current remarks array.
+
+=head2 B<org( [$org] )>
+
+Accessor to the org attribute.
+Accepts an optional org, always return the current org.
+
+Points to an existing organisation object representing the entity that
+holds the resource.
+
+The 'ORG-' string followed by 2 to 4 characters, followed by up to 5 digits
+followed by a source specification.  The first digit must not be "0".
+Source specification starts with "-" followed by source name up to
+9-character length.
+
+=head2 B<tech_c( [$contact] )>
+
+Accessor to the tech_c attribute.
+Accepts an optional contact to be added to the tech_c array,
+always return the current tech_c array.
+
+=head2 B<admin_c( [$contact] )>
+
+Accessor to the admin_c attribute.
+Accepts an optional contact to be added to the admin_c array,
+always return the current admin_c array.
+
+=head2 B<notify( [$notify] )>
+
+Accessor to the notify attribute.
+Accepts an optional notify value to be added to the notify array,
+always return the current notify array.
+
+=head2 B<mnt_by( [$mnt_by])>
+
+Accessor to the mnt_by attribute.
+Accepts an optional mnt_by value to be added to the mnt_by array,
+always return the current mnt_by array.
+
+=head2 B<changed( [$changed] )>
+
+Accessor to the changed attribute.
+Accepts an optional changed value to be added to the changed array,
+always return the current changed array.
+
+=head2 B<source( [$source] )>
+
+Accessor to the source attribute.
+Accepts an optional source, always return the current source.
+
+=head2 B<mp_members( [$mp_member] )>
+
+Accessor to the mp_members attribute.
+Accepts an optional mp_member to be added to the mp_members array,
+always return the current mp_members array.
+
+This attribute performs the same function as the members attribute above.
+The difference is that mp-members allows both IPv4 and IPv6 address families
+to be specified.
+
+Explicitly lists IPv4 or IPv6 'members' of the rtr-set can be:
+
+    * inet-rtr objects
+    * other rtr-set objects
+    * ipv4 address
+    * ipv6 address
+
+=cut
+
+1;
@@ -5,7 +5,7 @@ use base qw/Net::Whois::Object/;
 # http://www.ripe.net/data-tools/support/documentation/update-ref-manual#section-27
 # http://www.apnic.net/apnic-info/whois_search/using-whois/guide/rtr-set
 #
-# From : whois -t route-set
+# From: whois -t route-set
 # % This is the RIPE Database query service.
 # % The objects are in RPSL format.
 # %
@@ -3,9 +3,9 @@ use strict;
 use warnings;
 
 use Carp;
-use Net::Whois::RIPE;
 use IPC::Open2 qw/open2/;
 use List::Util qw/max/;
+use Data::Dumper;
 
 our $LWP;
 
@@ -23,10 +23,8 @@ Net::Whois::Object - Object encapsulating RPSL data returned by Whois queries
 =head1 SYNOPSIS
 
     use Net::Whois::RIPE;
-    use Net::Whois::Object;
-
-    my @objects = Net::Whois::Object->query('AS30781');
 
+    my @objects = Net::Whois::Generic->query('AS30781');
 
     # Or you can use the previous way
 
@@ -55,13 +53,13 @@ Before you had to filter objects using the class() method.
     # Then to only get the Person object (and ignore Information objects)
     my ($person) = grep {$_->class() eq 'Person'} Net::Whois::Object->new($iterator);
 
-But now the query() method allows you to filter more easily
+But now the query() from Net::Whois::Generic method allows you to filter more easily
 
-    my ($person) = Net::Whois::Object->query('POLK-RIPE', { type => 'person' });
+    my ($person) = Net::Whois::Generic->query('POLK-RIPE', { type => 'person' });
 
 You can even use the query() filtering capabilities a little further
 
-    my @emails = Net::Whois::Object->query('POLK-RIPE', { type => 'person', attribute => 'e_mail' });
+    my @emails = Net::Whois::Generic->query('POLK-RIPE', { type => 'person', attribute => 'e_mail' });
 
 Please note, that as soon as you use the attribute filter, the values returned
 are strings and no more Net::Whois::Objects.
@@ -71,7 +69,7 @@ are strings and no more Net::Whois::Objects.
     # Add a phone number
     $person->phone(' +33 4 88 00 65 15');
 
-Some attributes can have multiple value (remarks, mnt-by...) first implementation allowed only to
+Some attributes can have multiple values (remarks, mnt-by...) first implementation allowed only to
 add one value
 
     # Add one maintener
@@ -89,7 +87,14 @@ Which is a verbose way to do exactly as the default mode above, but also
 Or even
 
     # Replace CPNY-MNT2 by REPL-MNT
-    $person->mnt_by({mode => 'replace', value => {old => 'CPNY-MNT2', old => 'REPL-MNT'}});
+    $person->mnt_by({mode => 'replace', value => {old => 'CPNY-MNT2', new => 'REPL-MNT'}});
+
+From release 2.002 you can also use the 'delete' mode to remove a specific attribute value
+
+    $person->mnt_by({mode => 'delete', value => {old => 'REPL-MNT'}});
+    
+    # Or if you want to remove all remarks (the regex '.' meaning any char, will match all remarks values)
+    $person->remarks({mode => 'delete', value => {old => '.'}});
 
 
 =head2 Dump the current state of the data
@@ -107,7 +112,8 @@ dump() handle the 'align' parameter passed though a hash ref.
 =head2 Update the RIPE database
 
 The RIPE database update is currently under heavy development.
-*The update code is to be considered as experimental.*
+
+B<*The update code is still to be considered as experimental.*>
 
 We plan to offer several ways to update the RIPE database
 
@@ -146,7 +152,7 @@ array reference of additional options to pass to the signing binary.
 
 The primary key of the object created is returned.
 The attribute used as primary key can be obtained through 
-$object->attribute('primary') 
+C<$object->attribute('primary')>
 
 =head4 Update
 
@@ -244,7 +250,7 @@ sub new {
             $block = 'comment' unless $block;
 
             # Comment line
-            $attribute = "comment";
+            $attribute = 'comment';
             $value     = $1;
 
         } elsif ( $line =~ /^[^%]\s*(.+)/ ) {
@@ -255,10 +261,13 @@ sub new {
         } elsif ( $line =~ /^$/ ) {
 
             # Blank line
-            push @results, $object;
-            $attribute = undef;
-            $block     = undef;
-            $object    = undef;
+            if ($object) {
+                $object = _object_factory( $object->{block}, $object->{value}, $object );
+                push @results, $object;
+                $attribute = undef;
+                $block     = undef;
+                $object    = undef;
+            }
             next;
 
         }
@@ -270,14 +279,28 @@ sub new {
         $block = $attribute unless $block;
 
         if ( !$object ) {
-            $object = _object_factory( $block, $value ) unless $object;
-        } elsif ($attribute) {
-            $object->$attribute($value);
+            $object = { block => $block, value => $value, attributes => [] };
+
+            # $object = _object_factory( $block, $value ) unless $object;
+            # } elsif ( $object->can($attribute) ) {
+            # $object->$attribute($value);
+            if ( $block eq 'comment' ) {
+
+                # push @{$object->{attributes}},[ 'comment', $value ];
+                next;
+            }
         }
 
+        # } else {
+        push @{ $object->{attributes} }, [ $attribute, $value ];
+
+        # } else {
+        # warn "Objects of type " . ref($object) . " do not support attribute '$attribute', but it was supplied with value '$value'\n";
+        # }
+
     }
 
-    # TODO : fix the trailing undef
+    # TODO: fix the trailing undef
     return grep {defined} @results;
 }
 
@@ -326,7 +349,7 @@ sub clone {
 =head2 B<attributes( [$type [, \@attributes]] )>
 
 Accessor to the attributes of the object. 
-$type can be 
+C<$type> can be 
 
     'primary'   Primary/Lookup key
     'mandatory' Required for update creation
@@ -336,7 +359,7 @@ $type can be
     'all'       You can't specify attributes for this special type
                 which provides all the attributes which have a type
 
-If no $type is specified, 'all' is assumed.
+If no C<$type> is specified, 'all' is assumed.
 Returns a list of attributes of the required type.
 
 =cut
@@ -383,7 +406,7 @@ sub class {
 
 =head2 B<attribute_is ( $attribute, $type )>
 
-This method return true if $attribute is of type $type.
+This method return true if C<$attribute> is of type C<$type>
 
 =cut
 
@@ -426,7 +449,7 @@ sub displayed_attributes {
 Simple naive way to display a text form of the class.
 Try to be as close as possible as the submited text.
 
-Currently the only option available is 'align' which accept a $column number as
+Currently the only option available is 'align' which accept a C<$column> number as
 parameter so that all C<< $self->dump >> produces values that are aligned
 vertically on column C<$column>.
 
@@ -556,17 +579,34 @@ sub syncupdates_create {
         }
     }
 
-    my ($key) = $self->attributes('primary');
-
     my $res = $self->_syncupdates_submit( $self->dump($dump_options), $options );
 
     if (    $res =~ /^Number of objects processed with errors:\s+(\d+)/m
          && $1 == 0
-         && $res =~ /\*\*\*Info:\s+Authorisation for\s+\[[^\]]+]\s+(.+)\s*$/m )
+         && (    $res =~ /\*\*\*Info:\s+Authorisation for\s+\[[^\]]+]\s+(.+)\s*$/m
+              || $res =~ /(?:Create SUCCEEDED|No operation): \[[^\]]+\]\s+(\S+)/m )
+        )
     {
         my $value = $1;
-        $self->_single_attribute_setget( $key, $value );
-        return $value;
+        my ($key) = $self->attributes('primary');
+
+        # some primary keys can contain spaces, in which case $value
+        # is not correct. So only use it for objects where the primary
+        # key can be generated by the RIPE DB, and where it never contains
+        # spaces. According to
+        # http://www.ripe.net/ripe/mail/archives/db-help/2013-January/000411.html
+        # this is the case for person, organization, role and key-cert
+        my %obj_types_with_autogen_key = ( KeyCert      => 1,
+                                           Organisation => 1,
+                                           Person       => 1,
+                                           Role         => 1,
+        );
+        if ( $self->class && $obj_types_with_autogen_key{ $self->class } ) {
+            $self->_single_attribute_setget( $key, $value );
+            return $value;
+        } else {
+            return $self->$key();
+        }
     } else {
         croak "Error while creating object through syncupdates API: $res";
     }
@@ -574,63 +614,21 @@ sub syncupdates_create {
 
 =head2 B<query( $query, [\%options] )>
 
- ******************************** EXPERIMENTAL ************************************
-   This method is a work in progress, the API and behaviour are subject to change
- **********************************************************************************
+This method is deprecated since release 2.005 of Net::Whois::RIPE
 
-Query the RIPE database and return Net::Whois::Objects
-
-This method accepts 2 optional parameters
-
-'type' which is a regex used to filter the query result :
-Only the object whose type matches the 'type' parameter are returned
-
-'attribute' which is a regex used to filter the query result :
-Only the value of the attributes matching the 'attribute' parameter are
-returned
-
-Note that if 'attribute' is specified strings are returned, instead of
-Net::Whois::Objects
+Please use Net::Whois::Generic->query() instead.
 
 =cut
 
 sub query {
-    my ( $class, $query, $options ) = @_;
-
-    my $attribute;
-    my $type;
 
-    for my $opt ( keys %$options ) {
-        if ( $opt =~ /^attribute$/i ) {
-            $attribute = $options->{$opt};
-        } elsif ( $opt =~ /^type$/i ) {
-            $type = $options->{$opt};
-        }
-    }
+    croak "This method is deprecated since release 2.005 of Net::Whois::RIPE\nPlease use Net::Whois::Generic->query() instead\n";
 
-    my $whois    = Net::Whois::RIPE->new(%$options);
-    my $iterator = $whois->query($query);
-
-    my @objects = Net::Whois::Object->new($iterator);
-
-    if ($type) {
-        @objects = grep { ref($_) =~ /$type/i } @objects;
-    }
-
-    if ($attribute) {
-        return grep {defined} map {
-            my $r;
-            eval { $r = $_->$attribute };
-            $@ ? undef : ref($r) eq 'ARRAY' ? @$r : $r
-        } @objects;
-    } else {
-        return grep {defined} @objects;
-    }
 }
 
 =begin UNDOCUMENTED
 
-=head2 B<_object_factory( $type => $value )>
+=head2 B<_object_factory( $type => $value, $attributes_hashref )>
 
 Private method. Shouldn't be used from other modules.
 
@@ -640,8 +638,12 @@ the type passed as parameter.
 =cut
 
 sub _object_factory {
-    my $type  = shift;
-    my $value = shift;
+    my $type   = shift;
+    my $value  = shift;
+    my $object = shift;
+    my $rir;
+
+    my $object_returned;
 
     my %class = ( as_block     => 'AsBlock',
                   as_set       => 'AsSet',
@@ -657,7 +659,6 @@ sub _object_factory {
                   limerick     => 'Limerick',
                   mntner       => 'Mntner',
                   organisation => 'Organisation',
-                  organisation => 'Organisation',
                   peering_set  => 'PeeringSet',
                   person       => 'Person',
                   poem         => 'Poem',
@@ -670,24 +671,42 @@ sub _object_factory {
                   rtr_set      => 'RtrSet',
     );
 
-    die "Unrecognized Object (first attribute: $type = $value)" unless $class{$type};
+    die "Unrecognized Object (first attribute: $type = $value)\n" . Dumper($object) unless defined $type and $class{$type};
 
     my $class = "Net::Whois::Object::" . $class{$type};
 
+    for my $a ( @{ $object->{attributes} } ) {
+        if ( $a->[0] =~ /source/ ) {
+            $rir = $a->[1];
+            $rir =~ s/^(\S+)\s*#.*/$1/;
+            $rir = uc $rir;
+            $rir = undef if $rir =~ /^(RIPE|TEST)$/;    # For historical/compatibility reason RIPE objects aren't derived
+        }
+    }
+
+    $class .= "::$rir" if $rir;
+
     eval "require $class" or die "Can't require $class ($!)";
 
     # my $object = $class->new( $type => $value );
-    my $object = $class->new( class => $class{$type} );
+    $object_returned = $class->new( class => $class{$type} );
 
     # First attribute is always single valued, except for comments
     if ( $type eq 'comment' ) {
-        $object->_multiple_attribute_setget( $type => $value );
+        $object_returned->_multiple_attribute_setget( $type => $value );
     } else {
-        $object->_single_attribute_setget( $type => $value );
+        $object_returned->_single_attribute_setget( $type => $value );
+    }
+
+    if ( $object->{attributes} ) {
+        for my $a ( @{ $object->{attributes} } ) {
+            my $method = $a->[0];
+            $object_returned->$method( $a->[1] );
+        }
     }
 
     # return $class->new( $type => $value );
-    return $object;
+    return $object_returned;
 
 }
 
@@ -699,13 +718,38 @@ Generic setter/getter for singlevalue attribute.
 
 sub _single_attribute_setget {
     my ( $self, $attribute, $value ) = @_;
+    my $mode = 'replace';
+
+    if ( ref $value eq 'HASH' ) {
+        my %options = %$value;
+
+        if ( $options{mode} ) {
+            $mode = $options{mode};
+        }
+
+        if ( $options{value} ) {
+            $value = $options{value};
+        } else {
+            croak "Unable to determine attribute $attribute value";
+        }
+
+    }
 
     if ( defined $value ) {
 
-        # Store attribute order for dump, unless this attribute as already been set
-        push @{ $self->{order} }, $attribute unless $self->{$attribute} or $attribute eq 'class';
+        if ( $mode eq 'replace' ) {
+
+            # Store attribute order for dump, unless this attribute as already been set
+            push @{ $self->{order} }, $attribute unless $self->{$attribute} or $attribute eq 'class';
 
-        $self->{$attribute} = $value;
+            $self->{$attribute} = $value;
+        } elsif ( $mode eq 'delete' ) {
+            if ( ref $value ne 'HASH' or !$value->{old} ) {
+                croak " {old=>...} expected as value for $attribute update in delete mode";
+            } else {
+                $self->_delete_attribute( $attribute, $value->{old} );
+            }
+        }
     }
     return $self->{$attribute};
 }
@@ -756,6 +800,14 @@ sub _multiple_attribute_setget {
                     $_ = $value->{new} if $_ =~ /$old/;
                 }
             }
+        } elsif ( $mode eq 'delete' ) {
+            if ( ref $value ne 'HASH' or !$value->{old} ) {
+                croak " {old=>...} expected as value for $attribute update in delete mode";
+            } else {
+
+                # $self->{$attribute} = [grep {!/$old/} @{$self->{$attribute}}];
+                $self->_delete_attribute( $attribute, $value->{old} );
+            }
         } else {
             croak "Unknown mode $mode for attribute $attribute";
         }
@@ -765,6 +817,43 @@ sub _multiple_attribute_setget {
     return $self->{$attribute};
 }
 
+=head2 B<_delete_attribute( $attribute, $pattern )>
+
+Delete an attribute if its value match the pattern value 
+
+=cut
+
+sub _delete_attribute {
+    my ( $self, $attribute, $pattern ) = @_;
+
+    my @lines;
+
+    for my $a ( @{ $self->{order} } ) {
+        my $val = ref $self->{$a} ? shift @{ $self->{$a} } : $self->{$a};
+        push @lines, [ $a, $val ];
+    }
+
+    @lines = grep { $attribute ne $_->[0] or $_->[1] !~ /$pattern/ } @lines;
+    delete $self->{$attribute} if $self->attribute_is( $attribute, 'single' ) and $self->{$attribute} =~ /$pattern/;
+
+    $self->{order} = [];
+    for my $l (@lines) {
+        $self->{ $l->[0] } = [] if ref( $self->{ $l->[0] } );
+    }
+
+    for my $i ( 0 .. $#lines ) {
+        push @{ $self->{order} }, $lines[$i]->[0];
+        if ( $self->attribute_is( $lines[$i]->[0], 'multiple' ) ) {
+            push @{ $self->{ $lines[$i]->[0] } }, $lines[$i]->[1];
+        } else {
+            $self->{ $lines[$i]->[0] } = $lines[$i]->[1];
+
+        }
+
+    }
+
+}
+
 =head2 B<_init( @options )>
 
 Initialize self with C<@options>
@@ -866,6 +955,10 @@ sub _TYPE {
     $TYPES{ ref $_[0] || $_[0] } ||= {};
 }
 
+=head1 SEE ALSO
+
+Please take a look at L<Net::Whois::Generic> the more generic whois client built on top of Net::Whois::RIPE.
+
 =head1 TODO
 
 The update part (in RIPE database) still needs a lot of work.
@@ -3,23 +3,23 @@ package Net::Whois::RIPE;
 use 5.006;
 use warnings;
 use strict;
+use Net::Whois::Generic;
 use IO::Socket::INET;
 use IO::Select;
 use Iterator;
 
-use constant {
-    SOON                    => 30,
-    END_OF_OBJECT_MARK      => "\n\n",
-    EOL                     => "\015\012",
-    QUERY_KEEPALIVE         => q{-k },
-    QUERY_NON_RECURSIVE     => q{-r },
-    QUERY_REFERRAL          => q{-R },
-    QUERY_GROUPING          => q{-G },
-    QUERY_UNFILTERED        => q{-B },
-    QUERY_LIST_OBJECTS      => q{-qtypes },
-    QUERY_LIST_SOURCES      => q{-qsources },
-    QUERY_FETCH_TEMPLATE    => q{-t%s },
-    QUERY_LIMIT_OBJECT_TYPE => q{-T%s },
+use constant { SOON                    => 30,
+               END_OF_OBJECT_MARK      => "\n\n",
+               EOL                     => "\015\012",
+               QUERY_KEEPALIVE         => q{-k },
+               QUERY_NON_RECURSIVE     => q{-r },
+               QUERY_REFERRAL          => q{-R },
+               QUERY_GROUPING          => q{-G },
+               QUERY_UNFILTERED        => q{-B },
+               QUERY_LIST_OBJECTS      => q{-qtypes },
+               QUERY_LIST_SOURCES      => q{-qsources },
+               QUERY_FETCH_TEMPLATE    => q{-t%s },
+               QUERY_LIMIT_OBJECT_TYPE => q{-T%s },
 };
 
 =head1 NAME
@@ -28,11 +28,11 @@ Net::Whois::RIPE - a pure-Perl implementation of the RIPE Database client.
 
 =head1 VERSION
 
-Version 2.001000
+Version 2.005003
 
 =cut
 
-our $VERSION = 2.001000;
+our $VERSION = 2.005003;
 
 =head1 SYNOPSIS
 
@@ -50,18 +50,24 @@ The usage should remain mostly the same:
   my $whois = Net::Whois::RIPE->new( %options );
   $iterator = $whois->query( 'AS333' );
 
-If you prefer to manipulate full-fledged objects you can now use
+From version 2.005000 you can also use the  Net::Whois::Generic interface 
+that mimics Net::Whois::Object while offering access to data from other sources
+than RIPE (AFRINIC, APNIC)
 
-  use Net::Whois::Object;
+  use Net::Whois::RIPE;
 
-  my @objects = Net::Whois::Object->query( 'AS333' );
+  my @objects = Net::Whois::Generic->query( 'ORG-AFNC1-AFRINIC' );
+
+Please see L<Net::Whois::Generic> documentation for more details
 
 Of course, comments are more than welcome. If you believe you can help, please
 do not hesitate in contacting me.
 
 =head1 BACKWARD COMPATIBILITY
 
-I've choose to break backwards compatibility with older versions of the L<Net::Whois::RIPE> module for several different reasons. I will try to explain and justify them here, as design documentation. I will also strive to provide practical solutions for porting problems, if any.
+I've choose to break backwards compatibility with older versions of the L<Net::Whois::RIPE> 
+module for several different reasons. I will try to explain and justify them here, as design documentation. 
+I will also strive to provide practical solutions for porting problems, if any.
 
 =head2 Architecture
 
@@ -94,7 +100,7 @@ A production release of this module will be able to feed a L<RPSL::Parser> with
 RPSL objects extracted from the RIPE Database and return full-fledged objects
 containing a parsed version of the text (way more useful than a text blob, I
 believe). 
-Net::Whois::Object (from release 2.00_010) is the first attempt toward this
+L<Net::Whois::Object> (from release 2.00_010) is the first attempt toward this
 goal.
 
   # You can now do
@@ -183,25 +189,22 @@ connection to the RIPE Database service desired.
 =cut
 
 {
-    my %default_options = (
-        hostname     => 'whois.ripe.net',
-        port         => '43',
-        timeout      => 5,
-        keepalive    => 0,
-        referral     => 0,
-        recursive    => 0,
-        grouping     => 1,
-        unfiltered   => 0,
-        types        => undef,
-        disconnected => 0,
+    my %default_options = ( hostname     => 'whois.ripe.net',
+                            port         => '43',
+                            timeout      => 5,
+                            keepalive    => 0,
+                            referral     => 0,
+                            recursive    => 0,
+                            grouping     => 1,
+                            unfiltered   => 0,
+                            types        => undef,
+                            disconnected => 0,
     );
 
     sub new {
         my ( $class, %options ) = @_;
         my %known_options;
-        $known_options{$_}
-            = exists $options{$_} ? $options{$_} : $default_options{$_}
-            foreach keys %default_options;
+        $known_options{$_} = exists $options{$_} ? $options{$_} : $default_options{$_} foreach keys %default_options;
 
         my $self = bless { __options => \%known_options }, $class;
 
@@ -340,31 +343,25 @@ Initiates a connection with the current object's configuration.
 =cut
 
 sub connect {
-    my $self       = shift;
-    my %connection = (
-        Proto      => 'tcp',
-        Type       => SOCK_STREAM,
-        PeerAddr   => $self->hostname,
-        PeerPort   => $self->port,
-        Timeout    => $self->timeout,
-        Domain     => AF_INET,
-        Multihomed => 1,
+    my $self = shift;
+    my %connection = ( Proto      => 'tcp',
+                       Type       => SOCK_STREAM,
+                       PeerAddr   => $self->hostname,
+                       PeerPort   => $self->port,
+                       Timeout    => $self->timeout,
+                       Domain     => AF_INET,
+                       Multihomed => 1,
     );
 
     # Create a new IO::Socket object
-    my $socket = $self->{__state}{socket}
-        = IO::Socket::INET->new(%connection);
-    die q{Can't connect to "}
-        . $self->hostname . ':'
-        . $self->port
-        . qq{". Reason: [$@].\n}
+    my $socket = $self->{__state}{socket} = IO::Socket::INET->new(%connection);
+    die q{Can't connect to "} . $self->hostname . ':' . $self->port . qq{". Reason: [$@].\n}
         unless defined $socket;
 
     # Register $socket with the IO::Select object
     if ( my $ios = $self->ios ) {
         $ios->add($socket) unless $ios->exists($socket);
-    }
-    else {
+    } else {
         $self->{__state}{ioselect} = IO::Select->new($socket);
     }
 
@@ -437,7 +434,8 @@ sub disconnect {
     if ( $self->is_connected ) {
         my $socket = $self->{__state}{socket};
         $socket->close;
-        $self->{__state}{ioselect}->remove($socket);
+        $self->{__state}{ioselect}->remove($socket)
+            if $self->{__state}{ioselect};
         delete $self->{__state}{socket};
     }
 }
@@ -480,7 +478,7 @@ Sends a query to the server. Returns an L<Iterator> object that will return one
 sub query {
     my ( $self, $query ) = @_;
     my $parameters = "";
-    $parameters .= q{ } . QUERY_KEEPALIVE if $self->keepalive;
+    $parameters .= q{ } . QUERY_KEEPALIVE  if $self->keepalive;
     $parameters .= q{ } . QUERY_UNFILTERED if $self->unfiltered;
     $parameters .= q{ } . QUERY_NON_RECURSIVE unless $self->recursive;
     $parameters .= q{ } . QUERY_REFERRAL if $self->referral;
@@ -527,9 +525,9 @@ connection will be terminated after this query.
 =cut
 
 sub object_types {
-    my $self = shift;
+    my $self     = shift;
     my $iterator = $self->__query(QUERY_LIST_OBJECTS);
-    while (!$iterator->is_exhausted) {
+    while ( !$iterator->is_exhausted ) {
         my $value = $iterator->value;
         return split /\s+/, $value if $value !~ /^%\s/;
     }
@@ -624,3 +622,5 @@ This program is free software; you can redistribute it and/or modify it
 under the same terms as Perl itself.
 
 =cut
+
+1;
@@ -0,0 +1,4 @@
+use Test::More;
+eval 'use Test::CPAN::Changes';
+plan skip_all => 'Test::CPAN::Changes required for this test' if $@;
+changes_ok();
@@ -1,7 +1,6 @@
 use strict;
 use warnings;
 use Test::More qw( no_plan );
-use Test::Exception;
 
 # synchronizes the {error,standard} output of this test.
 use IO::Handle;
@@ -97,7 +96,8 @@ SKIP: {
     ok $c->is_connected, 'The client is connected.';
 
     # reconnect()
-    lives_ok { $c->reconnect } 'The client re-connected without dying.';
+    eval {$c->reconnect };
+    ok !$@,'The client re-connected without dying.';
     ok $c->is_connected, 'The client is connected (once more).';
 
     # ios()
@@ -111,17 +111,18 @@ SKIP: {
     # query()
     {
         my $iter;
-        lives_ok { $iter = $c->query('LMC-RIPE') }
-        q{Client performs queries without dying};
+        eval { $iter = $c->query('LMC-RIPE') };
+        ok !$@, q{Client performs queries without dying};
         isa_ok $iter, 'Iterator';
+        last unless $iter;
         ok $iter->isnt_exhausted, q{Iterator contains at least one result};
     }
 
     # object_types()
     {
         my @types;
-        lives_ok { @types = $c->object_types }
-        q{Client can retrieve available object types without dying.};
+        eval { @types = $c->object_types };
+        ok !$@ , q{Client can retrieve available object types without dying.};
         is $#types, 20,
           q{There are 21 known object types in the RIPE Database};
     }
@@ -129,9 +130,9 @@ SKIP: {
     # send()
 
     # disconnect()
-    lives_ok { $c->disconnect } 'The client disconnected without dying.';
+    eval { $c->disconnect };
+    ok !$@ , 'The client disconnected without dying.';
     ok !$c->is_connected, 'The client is not connected (anymore).';
 
     # DESTROY()
 }
-
@@ -1,7 +1,6 @@
 use strict;
 use warnings;
 use Test::More qw( no_plan );
-use Test::Exception;
 
 # synchronizes the {error,standard} output of this test.
 use IO::Handle;
@@ -30,6 +29,9 @@ can_ok $o[5], qw( aut_num as_name org source ), qw( descr member_of import mp_im
     mnt_lower mnt_by mnt_routes changed);
 ok( !$o[5]->can('bogusmethod'), "No AUTOLOAD interference with ${class}::AutNum tests" );
 
+#
+# 'attributes' method
+#
 is_deeply( [ $o[0]->attributes('mandatory') ], ['comment'] );
 
 is_deeply( [ $o[0]->attributes('optional') ], [] );
@@ -39,20 +41,32 @@ is_deeply( [ $o[0]->attributes('optional') ], [ 'opt1', 'opt2', 'opt3' ] );
 is_deeply( [ $o[0]->attributes('all') ], [ 'comment', 'opt1', 'opt2', 'opt3' ] );
 is_deeply( [ $o[0]->attributes() ],      [ 'comment', 'opt1', 'opt2', 'opt3' ] );
 
-is( $o[2]->dump, "% Information related to 'AS30720 - AS30895'\n" );
+#
+# 'dump' method
+#
+is( $o[2]->dump, "\% Information related to 'AS30720 - AS30895'\n" );
 is( $o[2]->dump( { align => 8 } ), "% Information related to 'AS30720 - AS30895'\n" );
 
-my $clone = $o[3]->clone;
-isa_ok($clone, ref $o[3], "Clone object has the same type of source");
-is_deeply($clone, $o[3], "Clone object deeply similar to source");
-
-$clone = $o[3]->clone({remove => ['source','remarks','org', 'admin-c', 'tech-c', 'mnt-by','mnt-lower']});
+#
+# 'clone' method
+#
+my $full_clone = $o[3]->clone;
+isa_ok($full_clone, ref $o[3], "Clone object has the same type of source");
+is_deeply($full_clone, $o[3], "Clone object deeply similar to source");
+my $clone = $o[3]->clone({remove => ['source','remarks','org', 'admin-c', 'tech-c', 'mnt-by','mnt-lower']});
 is_deeply($clone, { class => 'AsBlock', order => ['as_block', 'descr'], as_block => 'AS30720 - AS30895', descr => ['RIPE NCC ASN block'] }, "Clone object similar with removed attribute");
 
+#
+# default 'append' mode in attribute modification
+#
 $clone->mnt_by({value =>['MNT1-ADD','MNT2-ADD']});
 is_deeply($clone->mnt_by,['MNT1-ADD','MNT2-ADD'],'Array properly added to empty multiple attribute');
 $clone->mnt_by({value =>['MNT3-ADD','MNT4-ADD']});
 is_deeply($clone->mnt_by,['MNT1-ADD','MNT2-ADD','MNT3-ADD','MNT4-ADD'],'Array properly added to multiple attribute');
+
+#
+# 'replace' mode in attribute modification
+#
 $clone->mnt_by({mode => 'replace', value => { old => 'MNT3-ADD', new => 'MNT3-RPL'}});
 is_deeply($clone->mnt_by,['MNT1-ADD','MNT2-ADD','MNT3-RPL','MNT4-ADD'],'Array properly added to multiple attribute');
 eval { $clone->mnt_by({mode => 'unknown', value => { old => 'MNT3-ADD', new => 'MNT3-RPL'}}); };
@@ -62,26 +76,26 @@ like($@ ,qr/new.*replace mode/, "new=>... expected in replace mode");
 eval { $clone->mnt_by({mode => 'replace', value => { new => 'MNT3-ADD'}}); };
 like($@ ,qr/old.*replace mode/, "old=>... expected in replace mode");
 
+#
+# 'delete' mode in attribute modification
+#
+$clone->mnt_by({mode => 'delete', value => { old => 'MNT3-RPL'}});
+is_deeply($clone->mnt_by,['MNT1-ADD','MNT2-ADD','MNT4-ADD'],'Array properly deleted in to multiple attribute');
+eval { $clone->mnt_by({mode => 'delete', value => { new => 'MNT3-ADD'}}); };
+like($@ ,qr/old.*delete mode/, "old=>... expected in delete mode");
+$clone->mnt_by({mode => 'delete', value => { old => '.'}});
+is_deeply($clone->mnt_by,[],'Array properly emptyed through delete wildcard');
+like($clone->dump,qr/as-block:\s+AS30720 - AS30895\ndescr:\s+RIPE NCC ASN block\n/,"Dump of deleted attributes ok");
+my $delete_clone = $full_clone->clone({remove=>['remarks']});
+like($full_clone->dump,qr/as-block:\s+AS30720 - AS30895\ndescr:\s+RIPE NCC ASN block\nremarks:\s+These AS Numbers are further assigned to network\nremarks:\s+operators in the RIPE NCC service region. AS\nremarks:\s+assignment policy is documented in:\nremarks:\s+<http:\/\/www.ripe.net\/ripe\/docs\/asn-assignment.html>\nremarks:\s+RIPE NCC members can request AS Numbers using the\nremarks:\s+form available in the LIR Portal or at:\nremarks:\s+<http:\/\/www.ripe.net\/ripe\/docs\/asnrequestform.html>\norg:\s+ORG-NCC1-RIPE\nadmin-c:\s+CREW-RIPE\ntech-c:\s+RD132-RIPE\nmnt-by:\s+RIPE-DBM-MNT\nmnt-lower:\s+RIPE-NCC-HM-MNT\nsource:\s+RIPE # Filtered\n/,"org full clone stil ok");
+$full_clone->mnt_lower({mode=>'delete', value => {old => 'RIPE-NCC-HM-MNT'}});
+like($full_clone->dump,qr/as-block:\s+AS30720 - AS30895\ndescr:\s+RIPE NCC ASN block\nremarks:\s+These AS Numbers are further assigned to network\nremarks:\s+operators in the RIPE NCC service region. AS\nremarks:\s+assignment policy is documented in:\nremarks:\s+<http:\/\/www.ripe.net\/ripe\/docs\/asn-assignment.html>\nremarks:\s+RIPE NCC members can request AS Numbers using the\nremarks:\s+form available in the LIR Portal or at:\nremarks:\s+<http:\/\/www.ripe.net\/ripe\/docs\/asnrequestform.html>\norg:\s+ORG-NCC1-RIPE\nadmin-c:\s+CREW-RIPE\ntech-c:\s+RD132-RIPE\nmnt-by:\s+RIPE-DBM-MNT\nsource:\s+RIPE # Filtered\n$/,"non last attribute deletion ok");
+$full_clone->source({mode=>'delete', value => {old => 'RIPE'}});
+like($full_clone->dump,qr/as-block:\s+AS30720 - AS30895\ndescr:\s+RIPE NCC ASN block\nremarks:\s+These AS Numbers are further assigned to network\nremarks:\s+operators in the RIPE NCC service region. AS\nremarks:\s+assignment policy is documented in:\nremarks:\s+<http:\/\/www.ripe.net\/ripe\/docs\/asn-assignment.html>\nremarks:\s+RIPE NCC members can request AS Numbers using the\nremarks:\s+form available in the LIR Portal or at:\nremarks:\s+<http:\/\/www.ripe.net\/ripe\/docs\/asnrequestform.html>\norg:\s+ORG-NCC1-RIPE\nadmin-c:\s+CREW-RIPE\ntech-c:\s+RD132-RIPE\nmnt-by:\s+RIPE-DBM-MNT\n$/,"last attribute deletion ok");
+
 my @objects;
 eval { @objects = Net::Whois::Object->query('AS30781', {attribute => 'remarks'}) };
-
-SKIP: {
-    skip "Network issue",14 if ( $@ =~ /IO::Socket::INET/ );
-
-    for my $object (@objects) {
-        ok(!ref($object), "query() : String returned for 'remarks' attribute filter")
-    }
-
-    @objects = Net::Whois::Object->query('AS30781');
-    for my $object (@objects) {
-        ok(ref($object) =~ /Net::Whois::Object/ , "query() : Object returned for 'remarks' attribute filter")
-    }
-
-    @objects = Net::Whois::Object->query('AS30781', {type => 'asblock', attribute => 'admin_c'});
-    for my $object (@objects) {
-        ok($object eq 'CREW-RIPE' , "query() : 'CREW-RIPE' returned for AsBlock and admin-c filter")
-    }
-}
+like($@ ,qr/deprecated/i, "Deprecation warning for Net::Whois::Object->query()");
 
 __DATA__
 % This is the RIPE Database query service.
@@ -0,0 +1,120 @@
+use strict;
+use warnings;
+use Test::More qw( no_plan );
+
+# synchronizes the {error,standard} output of this test.
+# use IO::Handle;
+# STDOUT->autoflush(1);
+# STDERR->autoflush(1);
+
+our $class;
+BEGIN { $class = 'Net::Whois::Generic'; use_ok $class; }
+
+can_ok $class,
+
+  # Read-Only Accessors
+  qw( ios socket ),
+
+  # Read-Write Accessors
+  qw( hostname port timeout referral recursive grouping ),
+
+  # Connection Methods
+  qw( connect disconnect reconnect is_connected ),
+
+  # Query Methods
+  qw( query object_types send ),
+
+  # OO Support
+  qw( DESTROY );
+
+{
+    my $c = Net::Whois::Generic->new( disconnected => 1, unfiltered => 1 );
+    isa_ok $c, $class;
+
+}
+
+    my $c = $class->new( disconnected => 1 );
+
+    # connect()
+    eval { $c->connect };
+
+SKIP: {
+    skip "Network issue",14 if ( $@ =~ /IO::Socket::INET/ );
+
+    ok (!$@, "The client connected without dying. $@");
+
+    # is_connected()
+    ok $c->is_connected, 'The client is connected.';
+
+    # reconnect()
+    eval {$c->reconnect };
+    ok !$@,'The client re-connected without dying.';
+    ok $c->is_connected, 'The client is connected (once more).';
+
+    # ios()
+    isa_ok $c->ios, 'IO::Select';
+    ok $c->ios->count >= 1,
+      q{There's at least one handle registered with the IO::Select object.};
+ diag('count='.$c->ios->count); 
+
+    # socket()
+    isa_ok $c->socket, 'IO::Socket';
+
+    # query() RIPE
+    {
+        my $as_set;
+        eval { ($as_set) = $c->query('AS-JAGUAR', {type => 'AsSet'}) };
+        ok !$@, q{Client performs queries without dying $@};
+        isa_ok $as_set, 'Net::Whois::Object::AsSet';
+    }
+
+    # object_types()
+    {
+        my @types;
+        eval { @types = $c->object_types };
+        ok !$@ , q{Client can retrieve available object types without dying.};
+        is $#types, 20,
+          q{There are 21 known object types in the RIPE Database};
+    }
+
+    # send()
+
+    # disconnect()
+    eval { $c->disconnect };
+    ok !$@ , 'The client disconnected without dying.';
+    ok !$c->is_connected, 'The client is not connected (anymore).';
+
+    # DESTROY()
+}
+
+my @objects;
+
+eval { @objects = Net::Whois::Generic->query('AS30781', {attribute => 'remarks'}) };
+
+SKIP: {
+    skip "Network issue",14 if ( $@ =~ /IO::Socket::INET/ );
+
+    for my $object (@objects) {
+        ok(!ref($object), "query() : String returned for 'remarks' attribute filter")
+    }
+}
+
+eval {    @objects = Net::Whois::Generic->query('AS30781') };
+
+SKIP: {
+    skip "Network issue",14 if ( $@ =~ /IO::Socket::INET/ );
+    for my $object (@objects) {
+        ok(ref($object) =~ /Net::Whois::Object/ , "query() : Object ".ref($object)." returned for 'remarks' attribute filter")
+    }
+
+}
+
+eval {    @objects = Net::Whois::Generic->query('AS30781', {type => 'asblock', attribute => 'admin_c' })} ;
+
+SKIP: {
+    skip "Network issue",14 if ( $@ =~ /IO::Socket::INET/ );
+    for my $object (@objects) {
+        ok($object eq 'CREW-RIPE' , "query() : 'CREW-RIPE' returned for AsBlock and admin-c filter");
+        diag($object);
+    }
+}
@@ -1,7 +1,6 @@
 use strict;
 use warnings;
 use Test::More qw( no_plan );
-use Test::Exception;
 
 # synchronizes the {error,standard} output of this test.
 # use IO::Handle;
@@ -1,7 +1,6 @@
 use strict;
 use warnings;
 use Test::More qw( no_plan );
-use Test::Exception;
 use Net::Whois::Object;
 
 # synchronizes the {error,standard} output of this test.
@@ -66,6 +65,7 @@ is_deeply( $object->tech_c(), ['NC345-RIPE'], 'tech_c properly parsed' );
 $object->tech_c('Added tech_c');
 is( $object->tech_c()->[1], 'Added tech_c', 'tech_c properly added' );
 
+is( $object->tech_c()->[1], 'Added tech_c', 'tech_c properly added' );
 # Test 'mnt_by'
 $tested{'mnt_by'}++;
 is_deeply( $object->mnt_by(), [ 'RIPE-NCC-END-MNT', 'MAIN-FR-MNT' ], 'mnt_by properly parsed' );
@@ -1,7 +1,6 @@
 use strict;
 use warnings;
 use Test::More qw( no_plan );
-use Test::Exception;
 
 # synchronizes the {error,standard} output of this test.
 use IO::Handle;
@@ -1,7 +1,6 @@
 use strict;
 use warnings;
 use Test::More qw( no_plan );
-use Test::Exception;
 
 # synchronizes the {error,standard} output of this test.
 use IO::Handle;
@@ -1,7 +1,6 @@
 use strict;
 use warnings;
 use Test::More qw( no_plan );
-use Test::Exception;
 
 # synchronizes the {error,standard} output of this test.
 use IO::Handle;
@@ -1,7 +1,6 @@
 use strict;
 use warnings;
 use Test::More qw( no_plan );
-use Test::Exception;
 
 # synchronizes the {error,standard} output of this test.
 use IO::Handle;
@@ -1,7 +1,6 @@
 use strict;
 use warnings;
 use Test::More qw( no_plan );
-use Test::Exception;
 
 # synchronizes the {error,standard} output of this test.
 use IO::Handle;
@@ -1,7 +1,6 @@
 use strict;
 use warnings;
 use Test::More qw( no_plan );
-use Test::Exception;
 
 # synchronizes the {error,standard} output of this test.
 use IO::Handle;
@@ -131,9 +130,9 @@ is( $object->changed()->[1], 'abc@examplenet.com 20121231', 'changed properly ad
 
 # Test 'source'
 $tested{'source'}++;
-is( $object->source(), 'APNIC', 'source properly parsed' );
-$object->source('RIPE');
-is( $object->source(), 'RIPE', 'source properly set' );
+is( $object->source(), 'RIPE', 'source properly parsed' );
+$object->source('APNIC');
+is( $object->source(), 'APNIC', 'source properly set' );
 
 # Test 'org'
 $tested{'org'}++;
@@ -164,5 +163,5 @@ mnt-routes:  MAINT-EXAMPLENET-AP
 mnt-domains: MAINT-EXAMPLENET-AP
 mnt-irt:     IRT-EXAMPLENET-AP
 changed:     abc@examplenet.com 20101231
-source:      APNIC
+source:      RIPE
 
@@ -1,7 +1,6 @@
 use strict;
 use warnings;
 use Test::More qw( no_plan );
-use Test::Exception;
 
 # synchronizes the {error,standard} output of this test.
 use IO::Handle;
@@ -1,7 +1,6 @@
 use strict;
 use warnings;
 use Test::More qw( no_plan );
-use Test::Exception;
 
 # synchronizes the {error,standard} output of this test.
 use IO::Handle;
@@ -1,7 +1,6 @@
 use strict;
 use warnings;
 use Test::More qw( no_plan );
-use Test::Exception;
 
 # synchronizes the {error,standard} output of this test.
 use IO::Handle;
@@ -1,7 +1,6 @@
 use strict;
 use warnings;
 use Test::More qw( no_plan );
-use Test::Exception;
 
 # synchronizes the {error,standard} output of this test.
 use IO::Handle;
@@ -1,7 +1,6 @@
 use strict;
 use warnings;
 use Test::More qw( no_plan );
-use Test::Exception;
 
 # synchronizes the {error,standard} output of this test.
 use IO::Handle;
@@ -1,7 +1,6 @@
 use strict;
 use warnings;
 use Test::More qw( no_plan );
-use Test::Exception;
 
 # synchronizes the {error,standard} output of this test.
 use IO::Handle;
@@ -1,7 +1,6 @@
 use strict;
 use warnings;
 use Test::More qw( no_plan );
-use Test::Exception;
 
 # synchronizes the {error,standard} output of this test.
 use IO::Handle;
@@ -1,7 +1,6 @@
 use strict;
 use warnings;
 use Test::More qw( no_plan );
-use Test::Exception;
 
 # synchronizes the {error,standard} output of this test.
 use IO::Handle;
@@ -109,6 +108,8 @@ do 't/common.pl';
 ok( $tested{common_loaded}, "t/common.pl properly loaded" );
 ok( !$@, "Can evaluate t/common.pl ($@)" );
 
+
+
 __DATA__
 peering-set:    PRNG-EXAMPLE
 descr:          Peering at EXAMPLE
@@ -1,7 +1,6 @@
 use strict;
 use warnings;
 use Test::More qw( no_plan );
-use Test::Exception;
 
 # synchronizes the {error,standard} output of this test.
 use IO::Handle;
@@ -1,7 +1,6 @@
 use strict;
 use warnings;
 use Test::More qw( no_plan );
-use Test::Exception;
 
 # synchronizes the {error,standard} output of this test.
 use IO::Handle;
@@ -1,7 +1,6 @@
 use strict;
 use warnings;
 use Test::More qw( no_plan );
-use Test::Exception;
 
 # synchronizes the {error,standard} output of this test.
 use IO::Handle;
@@ -1,7 +1,6 @@
 use strict;
 use warnings;
 use Test::More qw( no_plan );
-use Test::Exception;
 
 # synchronizes the {error,standard} output of this test.
 use IO::Handle;
@@ -20,7 +19,7 @@ isa_ok $object, $class;
 
 # Non-inherited methods
 can_ok $object, qw( organisation org_name org_type descr remarks address phone
-    e_mail fax_no org admin_c tech_c ref_nfy mnt_ref notify mnt_by changed source);
+    e_mail fax_no org abuse_c admin_c tech_c ref_nfy mnt_ref notify mnt_by changed source);
 
 # Check if typed attributes are correct
 can_ok $object, $object->attributes('mandatory');
@@ -86,6 +85,12 @@ is_deeply( $object->language(), ['FR','EN'], 'language properly parsed' );
 $object->language('ES');
 is( $object->language()->[2], 'ES', 'language properly added' );
 
+# Test 'abuse_c'
+$tested{'abuse_c'}++;
+is( $object->abuse_c(), 'abuse@somewhere.com', 'abuse_c properly parsed' );
+$object->abuse_c('abuse3@somewhere.com');
+is( $object->abuse_c(), 'abuse3@somewhere.com', 'abuse_c properly changed' );
+
 # Test 'admin_c'
 $tested{'admin_c'}++;
 is_deeply( $object->admin_c(), ['CPNY-ADM'], 'admin_c properly parsed' );
@@ -170,6 +175,7 @@ phone:          +33 1 75 75 75 01
 fax-no:         +33 1 75 75 75 91
 e-mail:         someone@somewhere.com
 geoloc:         OTHER
+abuse-c:        abuse@somewhere.com
 language:       FR
 language:       EN
 admin-c:        CPNY-ADM
@@ -1,7 +1,6 @@
 use strict;
 use warnings;
 use Test::More qw( no_plan );
-use Test::Exception;
 
 # synchronizes the {error,standard} output of this test.
 use IO::Handle;
@@ -1,7 +1,6 @@
 use strict;
 use warnings;
 use Test::More qw( no_plan );
-use Test::Exception;
 
 # synchronizes the {error,standard} output of this test.
 use IO::Handle;
@@ -1,7 +1,6 @@
 use strict;
 use warnings;
 use Test::More qw( no_plan );
-use Test::Exception;
 
 # synchronizes the {error,standard} output of this test.
 use IO::Handle;
@@ -129,9 +128,9 @@ is( $object->changed()->[1], 'someone@demo.com 20120228', 'changed properly adde
 
 # Test 'source'
 $tested{'source'}++;
-is( $object->source(), 'APNIC', 'source properly parsed' );
-$object->source('RIPE');
-is( $object->source(), 'RIPE', 'source properly set' );
+is( $object->source(), 'RIPE', 'source properly parsed' );
+$object->source('APNIC');
+is( $object->source(), 'APNIC', 'source properly set' );
 
 # Common tests
 do 't/common.pl';
@@ -160,6 +159,6 @@ remarks:        24/24 7/7
 remarks:        https://www.demo.com
 changed:        someone@demo.com 20120131
 notify:         someone@demo.com
-source:         APNIC
+source:         RIPE
 
 
@@ -1,7 +1,6 @@
 use strict;
 use warnings;
 use Test::More qw( no_plan );
-use Test::Exception;
 
 # synchronizes the {error,standard} output of this test.
 use IO::Handle;
@@ -1,7 +1,6 @@
 use strict;
 use warnings;
 use Test::More;
-use Test::Exception;
 use Net::Whois::RIPE;
 use Net::Whois::Object;
 
@@ -23,7 +22,7 @@ unless ($LWP) {
     plan skip_all => 'LWP::UserAgent installation required for update';
 }
 
-plan tests => 5;
+plan tests => 6;
 
 my $MNTNER = $ENV{TEST_MNTNER};
 my $PASSWD = $ENV{TEST_MNTNER_PASSWORD};
@@ -39,9 +38,10 @@ my $email_before = $person->e_mail()->[0];
 
 my $person_id = $person->syncupdates_create( { password => $PASSWD, align => 8 } );
 ok($person_id);
+ok($person_id ne 'AUTO-1', 'person ID has been generated by RIPE db');
 
 my $whois = Net::Whois::RIPE->new( hostname => 'whois-test.ripe.net' );
-my $iterator = $whois->query($person_id);
+my $iterator = $whois->query(" -B $person_id");
 
 ($person) = grep { ( $_->class() eq 'Person' ) and ( $_->nic_hdl eq $person_id ) } Net::Whois::Object->new($iterator);
 
@@ -50,7 +50,7 @@ my $email_after = $person->e_mail('arhuman2@gmail.com');
 
 $person->syncupdates_update( { password => $PASSWD, align => 10 } );
 
-$iterator = $whois->query($person_id);
+$iterator = $whois->query("-B $person_id");
 ($person) = grep { ( $_->class() eq 'Person' ) and ( $_->nic_hdl eq $person_id ) } Net::Whois::Object->new($iterator);
 
 is_deeply( $person->e_mail(), $email_after, "Same as set name" );
@@ -66,6 +66,17 @@ $iterator = $whois->query($person_id);
 
 like( $person->response, qr/ERROR:101:/, 'Deleted Person not found' );
 
+$iterator = $whois->query("-B AS1");
+
+
+#print STDERR grep { ( $_->class() eq 'AutNum' ) } Net::Whois::Object->new($iterator);
+for my $o (Net::Whois::Object->new($iterator)) {
+    print STDERR "$o\n";
+    print STDERR $o->dump;
+}
+
+print STDERR  Net::Whois::Object->new($iterator);
+
 __DATA__
 person: Joh Doe
 address: 1 Avenue de la Gare
@@ -0,0 +1,85 @@
+use strict;
+use warnings;
+use Test::More;
+use Net::Whois::RIPE;
+use Net::Whois::Object;
+
+our $LWP;
+BEGIN {
+    $LWP = do {
+        eval {
+            require LWP::UserAgent;
+        };
+        ($@) ? 0 : 1;
+    };
+}
+
+unless ( $ENV{TEST_MNTNER} && $ENV{TEST_MNTNER_PGPKEY} ) {
+    warn(<<'WARNING');
+
+Set TEST_MNTNER, TEST_MNTNER_PGPKEY environment vars for live testing
+    TEST_MNTNER being a maintener's nic-hdl in the RIPE test database
+    TEST_MNTNER_PGPKEY being the key ID of an key-cert associated with
+    the maintainer object
+WARNING
+    plan skip_all => ' Set environment vars for server testing';
+}
+
+unless ($LWP) {
+    plan skip_all => 'LWP::UserAgent installation required for update';
+}
+
+plan tests => 5;
+
+my $MNTNER = $ENV{TEST_MNTNER};
+my $PGPKEY = $ENV{TEST_MNTNER_PGPKEY};
+
+my @lines = <DATA>;
+map {s/MNTNER/$MNTNER/} @lines;
+
+my @o      = Net::Whois::Object->new(@lines);
+my $person = shift @o;
+my $mntner = shift @o;
+
+my $email_before = $person->e_mail()->[0];
+
+my $person_id = $person->syncupdates_create( { pgpkey => $PGPKEY } );
+ok($person_id);
+
+my $whois = Net::Whois::RIPE->new( hostname => 'whois-test.ripe.net' );
+my $iterator = $whois->query($person_id);
+
+($person) = grep { ( $_->class() eq 'Person' ) and ( $_->nic_hdl eq $person_id ) } Net::Whois::Object->new($iterator);
+
+is_deeply( $person->e_mail(), [$email_before], "Same name from previous" );
+my $email_after = $person->e_mail('arhuman2@gmail.com');
+
+$person->syncupdates_update( { pgpkey => $PGPKEY } );
+
+$iterator = $whois->query($person_id);
+($person) = grep { ( $_->class() eq 'Person' ) and ( $_->nic_hdl eq $person_id ) } Net::Whois::Object->new($iterator);
+
+is_deeply( $person->e_mail(), $email_after, "Same as set name" );
+
+isa_ok( $person, 'Net::Whois::Object::Person', 'Found a Person' );
+
+$person->syncupdates_delete( { pgpkey => $PGPKEY } );
+
+$whois = Net::Whois::RIPE->new( hostname => 'whois-test.ripe.net' );
+$iterator = $whois->query($person_id);
+
+($person) = grep { $_->class() eq 'Response' } Net::Whois::Object->new($iterator);
+
+like( $person->response, qr/ERROR:101:/, 'Deleted Person not found' );
+
+__DATA__
+person: Joh Doe
+address: 1 Avenue de la Gare
+address: 75001 Paris
+phone: +33 1 01 01 01 01
+e-mail: arhuman@gmail.com
+nic-hdl: AUTO-1
+mnt-by: MNTNER
+changed: arhuman@gmail.com 
+source: TEST
+
@@ -0,0 +1,27 @@
+use strict;
+use warnings;
+
+use Test::More qw(no_plan);
+
+use_ok 'Net::Whois::Generic';
+
+my $c = Net::Whois::Generic->new( disconnected => 1, unfiltered => 1 );
+isa_ok $c, 'Net::Whois::Generic';
+
+my $org;
+eval { ($org) = $c->query( 'ORG-AFNC1-AFRINIC', { type => 'organisation' } ) };
+
+SKIP: {
+    skip "Network issue",14 if ( $@ =~ /IO::Socket::INET/ );
+
+    ok !$@, qq{Client performs queries without dying $@};
+    isa_ok $org, 'Net::Whois::Object::Organisation::AFRINIC';
+
+    my @o;
+    eval { @o = $c->query('105.0.0.1') };
+    ok !$@, qq{Client performs queries without dying $@};
+    for my $o (@o) {
+        my $type = ref $o;
+        ok( $type =~ /(AFRINIC|Information)/, "Object " . $o->class . " returned" );
+    }
+}
@@ -0,0 +1,27 @@
+use strict;
+use warnings;
+
+use Test::More qw(no_plan);
+
+use_ok 'Net::Whois::Generic';
+
+my $c = Net::Whois::Generic->new( disconnected => 1, unfiltered => 0 );
+isa_ok $c, 'Net::Whois::Generic';
+
+my $mntner;
+eval { ($mntner) = $c->query( 'MAINT-APNIC-AP', { type => 'mntner' } ) };
+
+SKIP: {
+    skip "Network issue",14 if ( $@ =~ /IO::Socket::INET/ );
+
+    ok !$@, qq{Client performs queries without dying $@};
+    isa_ok $mntner, 'Net::Whois::Object::Mntner::APNIC';
+
+    my @o;
+    eval { @o = $c->query('101.0.0.0/8') };
+    ok !$@, qq{Client performs queries without dying $@};
+    for my $o (@o) {
+        my $type = ref $o;
+        ok( $type =~ /(APNIC|Information)/, "Object " . $o->class . " returned" );
+    }
+}
@@ -35,9 +35,6 @@ for my $a ( $object->attributes('multiple') ) {
 # Check that all attributes have been tested
 
 for my $a ( $object->attributes('all') ) {
-    # Check that each attribute has been tested
-    ok ($tested{ $a }, "Attribute $a has been tested");
-
     # Check that each attribute is set either to 'single' or 'multiple'
     ok ($object->attribute_is($a, 'single') or $object->attribute_is($a, 'multiple'), "$a is either single or multiple");
     ok ($object->attribute_is($a, 'single') != $object->attribute_is($a, 'multiple'), "$a can't be both single".$object->attribute_is($a,'single')." and multi".$object->attribute_is($a,'multiple'));