diff --git a/tools/winapi/config.pm b/tools/winapi/config.pm
index 6e7aa8e149871719ef1a1a135cb17ff5123eef21..852ef8b82140bd7149c64a345ad1fccbc3b5abbb 100644
--- a/tools/winapi/config.pm
+++ b/tools/winapi/config.pm
@@ -20,7 +20,7 @@ require Exporter;
 
 use vars qw($current_dir $wine_dir $winapi_dir $winapi_check_dir);
 
-my $output = "output";
+use output qw($output);
 
 sub file_type {
     local $_ = shift;
diff --git a/tools/winapi/options.pm b/tools/winapi/options.pm
index 95eb23566fe3adf3e23419cbf5af458a3519eb58..6ff005fd90d711b721233799917c5933928e4080 100644
--- a/tools/winapi/options.pm
+++ b/tools/winapi/options.pm
@@ -6,10 +6,10 @@ use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
 require Exporter;
 
 @ISA = qw(Exporter);
-@EXPORT = qw(&parse_comma_list);
-@EXPORT_OK = qw();
+@EXPORT = qw();
+@EXPORT_OK = qw($options &parse_comma_list);
 
-my $output = "output";
+use vars qw($options);
 
 sub parse_comma_list {
     my $prefix = shift;
@@ -27,27 +27,13 @@ sub parse_comma_list {
     }
 }
 
-my $_options;
-
-sub new {
-    my $self = shift;
-    $_options = _options->new(@_);
-    return $_options;
-}
-
-sub AUTOLOAD {
-    my $self = shift;
-
-    my $name = $options::AUTOLOAD;
-    $name =~ s/^.*::(.[^:]*)$/$1/;
-
-    return $_options->$name(@_);
-}
-
 package _options;
 
 use strict;
 
+use config qw($current_dir $wine_dir);
+use output qw($output);
+
 sub new {
     my $proto = shift;
     my $class = ref($proto) || $proto;
@@ -209,8 +195,8 @@ sub new {
 	} split(/\n/, `$c_command`));
     }
 
-    if($#h_files != -1) {
-	my $h_command = "find " . join(" ", @h_files) . " -name \\*.h";
+    if($#paths != -1 || $#h_files != -1) {
+	my $h_command = "find " . join(" ", @paths, @h_files) . " -name \\*.h";
 	my %found;
 
 	@$h_files = sort(map {
diff --git a/tools/winapi/output.pm b/tools/winapi/output.pm
index 1b461728d4fcdbddb0283e059c609bb47db68d87..7c9bf0d427cbeb1667f418c97eec77a7abd93177 100644
--- a/tools/winapi/output.pm
+++ b/tools/winapi/output.pm
@@ -2,22 +2,16 @@ package output;
 
 use strict;
 
-my $_output;
+use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
+require Exporter;
 
-sub new {
-    my $self = shift;
-    $_output = _output->new(@_);
-    return $_output;
-}
+@ISA = qw(Exporter);
+@EXPORT = qw();
+@EXPORT_OK = qw($output);
 
-sub AUTOLOAD {
-    my $self = shift;
+use vars qw($output);
 
-    my $name = $output::AUTOLOAD;
-    $name =~ s/^.*::(.[^:]*)$/$1/;
-
-    return $_output->$name(@_);
-}
+$output = '_output'->new;
 
 package _output;
 
@@ -37,17 +31,18 @@ sub new {
     my $last_time = \${$self->{LAST_TIME}};
     my $progress_count = \${$self->{PROGRESS_COUNT}};
     my $prefix = \${$self->{PREFIX}};
+    my $prefix_callback = \${$self->{PREFIX_CALLBACK}};
 
     $$progress = "";
     $$last_progress = "";
     $$last_time = 0;
     $$progress_count = 0;
-    $$prefix = "";
+    $$prefix = undef;
+    $$prefix_callback = undef;
 
     return $self;
 }
 
-
 sub show_progress {
     my $self = shift;
     my $progress = \${$self->{PROGRESS}};
@@ -134,8 +129,20 @@ sub lazy_progress {
 sub prefix {
     my $self = shift;
     my $prefix = \${$self->{PREFIX}};
+    my $prefix_callback = \${$self->{PREFIX_CALLBACK}};
 
     $$prefix = shift;
+    $$prefix_callback = undef;
+}
+
+sub prefix_callback {
+    my $self = shift;
+
+    my $prefix = \${$self->{PREFIX}};
+    my $prefix_callback = \${$self->{PREFIX_CALLBACK}};
+
+    $$prefix = undef;
+    $$prefix_callback = shift;
 }
 
 sub write {
@@ -144,9 +151,16 @@ sub write {
     my $message = shift;
 
     my $prefix = \${$self->{PREFIX}};
+    my $prefix_callback = \${$self->{PREFIX_CALLBACK}};
 
     $self->hide_progress if $stdout_isatty;
-    print $$prefix . $message;
+    if(defined($$prefix)) {
+	print $$prefix . $message;
+    } elsif(defined($$prefix_callback)) {
+	print &{$$prefix_callback}() . $message;
+    } else {
+	print $message;
+    }
     $self->show_progress if $stdout_isatty;
 }
 
diff --git a/tools/winapi/winapi_check_options.pm b/tools/winapi/winapi_check_options.pm
new file mode 100644
index 0000000000000000000000000000000000000000..22d5e8a466fa2dc862641dd8195ff525d0bf203c
--- /dev/null
+++ b/tools/winapi/winapi_check_options.pm
@@ -0,0 +1,177 @@
+package winapi_check_options;
+use base qw(options);
+
+use strict;
+
+use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
+require Exporter;
+
+@ISA = qw(Exporter);
+@EXPORT = qw();
+@EXPORT_OK = qw($options);
+
+use config qw($current_dir $wine_dir);
+use options qw($options &parse_comma_list);
+
+my %options_long = (
+    "debug" => { default => 0, description => "debug mode" },
+    "help" => { default => 0, description => "help mode" },
+    "verbose" => { default => 0, description => "verbose mode" },
+
+    "progress" => { default => 1, description => "show progress" },
+
+    "win16" => { default => 1, description => "Win16 checking" },
+    "win32" => { default => 1, description => "Win32 checking" },
+
+    "shared" =>  { default => 0, description => "show shared functions between Win16 and Win32" },
+    "shared-segmented" =>  { default => 0, description => "segmented shared functions between Win16 and Win32 checking" },
+
+    "config" => { default => 1, parent => "local", description => "check configuration include consistancy" },
+    "config-unnessary" => { default => 0, parent => "config", description => "check for unnessary #include \"config.h\"" },
+
+    "spec-mismatch" => { default => 0, description => "spec file mismatch checking" },
+
+    "local" =>  { default => 1, description => "local checking" },
+    "module" => { 
+	default => { active => 1, filter => 0, hash => {} },
+	parent => "local",
+	parser => \&parser_comma_list,
+	description => "module filter"
+    },
+
+    "argument" => { default => 1, parent => "local", description => "argument checking" },
+    "argument-count" => { default => 1, parent => "argument", description => "argument count checking" },
+    "argument-forbidden" => {
+	default => { active => 1, filter => 0, hash => {} },
+	parent => "argument",
+	parser => \&parser_comma_list,
+	description => "argument forbidden checking"
+    },
+    "argument-kind" => {
+	default => { active => 1, filter => 1, hash => { double => 1 } },
+	parent => "argument",
+	parser => \&parser_comma_list,
+	description => "argument kind checking"
+    },
+    "calling-convention" => { default => 1, parent => "local", description => "calling convention checking" },
+    "calling-convention-win16" => { default => 0, parent => "calling-convention", description => "calling convention checking (Win16)" },
+    "calling-convention-win32" => { default => 1, parent => "calling-convention", description => "calling convention checking (Win32)" },
+    "misplaced" => { default => 1, parent => "local", description => "check for misplaced functions" },
+    "statements"  => { default => 0, parent => "local", description => "check for statements inconsistances" },
+    "cross-call" => { default => 0, parent => "statements",  description => "check for cross calling functions" },
+    "cross-call-win32-win16" => { 
+	default => 0, parent => "cross-call", description => "check for cross calls between win32 and win16"
+     },
+    "cross-call-unicode-ascii" => { 
+	default => 0, parent => "cross-call", description => "check for cross calls between Unicode and ASCII" 
+    },
+    "debug-messages" => { default => 0, parent => "statements", description => "check for debug messages inconsistances" },
+
+    "documentation" => {
+	default => 1,
+	parent => "local", 
+	description => "check for documentation inconsistances"
+	},
+    "documentation-pedantic" => { 
+	default => 0, 
+	parent => "documentation", 
+	description => "be pendantic when checking for documentation inconsistances"
+	},
+
+    "documentation-arguments" => {
+	default => 1,
+	parent => "documentation",
+	description => "check for arguments documentation inconsistances\n"
+	},
+    "documentation-comment-indent" => {
+	default => 0, 
+	parent => "documentation", description => "check for documentation comment indent inconsistances"
+	},
+    "documentation-comment-width" => {
+	default => 0, 
+	parent => "documentation", description => "check for documentation comment width inconsistances"
+	},
+    "documentation-name" => {
+	default => 1,
+	parent => "documentation",
+	description => "check for documentation name inconsistances\n"
+	},
+    "documentation-ordinal" => {
+	default => 1,
+	parent => "documentation",
+	description => "check for documentation ordinal inconsistances\n"
+	},
+    "documentation-wrong" => {
+	default => 1,
+	parent => "documentation",
+	description => "check for wrong documentation\n"
+	},
+
+    "prototype" => {default => 0, parent => ["local", "headers"], description => "prototype checking" },
+    "global" => { default => 1, description => "global checking" },
+    "declared" => { default => 1, parent => "global", description => "declared checking" },
+    "implemented" => { default => 0, parent => "local", description => "implemented checking" },
+    "implemented-win32" => { default => 0, parent => "implemented", description => "implemented as win32 checking" },
+    "include" => { default => 1, parent => "global", description => "include checking" },
+
+    "headers" => { default => 0, description => "headers checking" },
+    "headers-duplicated" => { default => 0, parent => "headers", description => "duplicated function declarations checking" },
+    "headers-misplaced" => { default => 0, parent => "headers", description => "misplaced function declarations checking" },
+    "headers-needed" => { default => 1, parent => "headers", description => "headers needed checking" },
+    "headers-unused" => { default => 0, parent => "headers", description => "headers unused checking" },
+);
+
+my %options_short = (
+    "d" => "debug",
+    "?" => "help",
+    "v" => "verbose"
+);
+
+my $options_usage = "usage: winapi_fixup [--help] [<files>]\n";
+
+$options = '_winapi_check_options'->new(\%options_long, \%options_short, $options_usage);
+
+my $global = \${$options->{GLOBAL}};
+
+if($wine_dir ne ".") {
+    $$global = 0;
+}
+
+package _winapi_check_options;
+use base qw(_options);
+
+use strict;
+
+sub report_module {
+    my $self = shift;
+    my $refvalue = $self->{MODULE};
+    
+    my $name = shift;
+
+    if(defined($name)) {
+	return $$refvalue->{active} && (!$$refvalue->{filter} || $$refvalue->{hash}->{$name}); 
+    } else {
+	return 0;
+    } 
+}
+
+sub report_argument_forbidden {
+    my $self = shift;   
+    my $refargument_forbidden = $self->{ARGUMENT_FORBIDDEN};
+
+    my $type = shift;
+
+    return $$refargument_forbidden->{active} && (!$$refargument_forbidden->{filter} || $$refargument_forbidden->{hash}->{$type}); 
+}
+
+sub report_argument_kind {
+    my $self = shift;
+    my $refargument_kind = $self->{ARGUMENT_KIND};
+
+    my $kind = shift;
+
+    return $$refargument_kind->{active} && (!$$refargument_kind->{filter} || $$refargument_kind->{hash}->{$kind}); 
+
+}
+
+1;
diff --git a/tools/winapi/winapi_extract b/tools/winapi/winapi_extract
index de72ae0dff0d1dd117079716a2d8532cab64e0ba..c93c1e29e20a89f73a2363ff686a6e1528a2a5bf 100755
--- a/tools/winapi/winapi_extract
+++ b/tools/winapi/winapi_extract
@@ -15,40 +15,12 @@ use config qw(
 );
 use modules;
 use nativeapi;
-use output;
+use output qw($output);
 use options;
 use winapi;
 use winapi_function;
 use winapi_parser;
-
-my $output = 'output'->new;
-
-my %options_long = (
-    "debug" => { default => 0, description => "debug mode" },
-    "help" => { default => 0, description => "help mode" },
-    "verbose" => { default => 0, description => "verbose mode" },
-
-    "progress" => { default => 1, description => "show progress" },
-
-    "win16" => { default => 1, description => "Win16 extraction" },
-    "win32" => { default => 1, description => "Win32 extraction" },
-
-    "local" =>  { default => 1, description => "local extraction" },
-    "global" => { default => 1, description => "global extraction" },
-
-    "spec-files" => { default => 1, parent => "global", description => "spec files extraction" },
-    "stub-statistics" => { default => 0, parent => "global", description => "stub statistics" },
-);
-
-my %options_short = (
-    "d" => "debug",
-    "?" => "help",
-    "v" => "verbose"
-);
-
-my $options_usage = "usage: winapi_extract [--help] [<files>]\n";
-
-my $options = 'options'->new(\%options_long, \%options_short, $options_usage);
+use winapi_extract_options qw($options);
 
 my %module2spec_file;
 my %module2type;
@@ -104,7 +76,6 @@ sub documentation_specifications {
     my $return_type = $function->return_type;
     my $linkage = $function->linkage;
     my $internal_name = $function->internal_name;
-    my @argument_types = @{$function->argument_types};
 
     if($linkage eq "static") {
 	return;
@@ -203,14 +174,11 @@ foreach my $file (@c_files) {
 	my $return_type = $function->return_type;
 	my $calling_convention = $function->calling_convention;
 	my $internal_name = $function->internal_name;
-	my @argument_types = @{$function->argument_types};
-	my @argument_names = @{$function->argument_names};
-	my @argument_documentations = @{$function->argument_documentations};
 	my $statements = $function->statements;
 
 	$functions{$internal_name} = $function;
 
-	$output->prefix("$file: " . $function->prefix);
+	$output->prefix_callback(sub { return $function->prefix; });
 
 	if($options->spec_files) {
 	    documentation_specifications($function);
@@ -228,7 +196,7 @@ foreach my $file (@c_files) {
 	my $argument = shift;
     };
 
-    winapi_parser::parse_c_file $options, $output, $file, $found_function, $found_preprocessor;
+    &winapi_parser::parse_c_file($options, $file, $found_function, $found_preprocessor);
 
     my @internal_names = keys(%functions);
     if($#internal_names < 0) {
@@ -247,18 +215,23 @@ sub output_function {
 
     my $return_kind;
     my $calling_convention;
-    my @argument_kinds;
+    my $refargument_kinds;
     if($type eq "win16") {
 	$return_kind = $function->return_kind16 || "undef";
 	$calling_convention = $function->calling_convention16 || "undef";
-	@argument_kinds = map { $_ || "undef"; } @{$function->argument_kinds16};
+	$refargument_kinds = $function->argument_kinds16;
     } elsif($type eq "win32") {
 	$return_kind = $function->return_kind32 || "undef";
 	$calling_convention = $function->calling_convention32 || "undef";
-	@argument_kinds = map { $_ || "undef"; } @{$function->argument_kinds32};
+	$refargument_kinds = $function->argument_kinds32;
     }
 
-    print OUT "$ordinal $calling_convention $external_name(@argument_kinds) $internal_name\n";
+    if(defined($refargument_kinds)) {
+	my @argument_kinds = map { $_ || "undef"; } @$refargument_kinds;
+	print OUT "$ordinal $calling_convention $external_name(@argument_kinds) $internal_name\n";
+    } else {
+	print OUT "$ordinal $calling_convention $external_name() $internal_name # FIXME: arguments undefined\n";
+    }
 }
 
 if($options->spec_files) {
diff --git a/tools/winapi/winapi_extract_options.pm b/tools/winapi/winapi_extract_options.pm
new file mode 100644
index 0000000000000000000000000000000000000000..0e4e978200004d6bd4b5e9e886186fdf1129e0bb
--- /dev/null
+++ b/tools/winapi/winapi_extract_options.pm
@@ -0,0 +1,42 @@
+package winapi_extract_options;
+use base qw(options);
+
+use strict;
+
+use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
+require Exporter;
+
+@ISA = qw(Exporter);
+@EXPORT = qw();
+@EXPORT_OK = qw($options);
+
+use options qw($options &parse_comma_list);
+
+my %options_long = (
+    "debug" => { default => 0, description => "debug mode" },
+    "help" => { default => 0, description => "help mode" },
+    "verbose" => { default => 0, description => "verbose mode" },
+
+    "progress" => { default => 1, description => "show progress" },
+
+    "win16" => { default => 1, description => "Win16 extraction" },
+    "win32" => { default => 1, description => "Win32 extraction" },
+
+    "local" =>  { default => 1, description => "local extraction" },
+    "global" => { default => 1, description => "global extraction" },
+
+    "spec-files" => { default => 1, parent => "global", description => "spec files extraction" },
+    "stub-statistics" => { default => 0, parent => "global", description => "stub statistics" },
+);
+
+my %options_short = (
+    "d" => "debug",
+    "?" => "help",
+    "v" => "verbose"
+);
+
+my $options_usage = "usage: winapi_extract [--help] [<files>]\n";
+
+$options = '_options'->new(\%options_long, \%options_short, $options_usage);
+
+1;
diff --git a/tools/winapi/winapi_fixup b/tools/winapi/winapi_fixup
index a10dc4c9f34cc874d228ad1aa588a0b736b1eb13..4a87ba222652afc2b883458aabe33b97bcabc455 100755
--- a/tools/winapi/winapi_fixup
+++ b/tools/winapi/winapi_fixup
@@ -16,47 +16,12 @@ use config qw(
     &get_spec_files
     $current_dir $wine_dir $winapi_dir $winapi_check_dir
 );
-use output;
-use options;
+use output qw($output);
 use modules;
 use util;
 use winapi;
 use winapi_parser;
-
-my $output = 'output'->new;
-
-my %options_long = (
-    "debug" => { default => 0, description => "debug mode" },
-    "help" => { default => 0, description => "help mode" },
-    "verbose" => { default => 0, description => "verbose mode" },
-
-    "progress" => { default => 1, description => "show progress" },
-
-    "win16" => { default => 1, description => "Win16 fixup" },
-    "win32" => { default => 1, description => "Win32 fixup" },
-
-    "local" =>  { default => 1, description => "local fixup" },
-    "documentation" => { default => 1, parent => "local", description => "documentation fixup" },
-    "documentation-missing" => { default => 1, parent => "documentation", description => "documentation missing fixup" },
-    "documentation-name" => { default => 1, parent => "documentation", description => "documentation name fixup" },
-    "documentation-ordinal" => { default => 1, parent => "documentation", description => "documentation ordinal fixup" },
-    "documentation-wrong" => { default => 1, parent => "documentation", description => "documentation wrong fixup" },
-    "stub" => { default => 0, parent => "local", description => "stub fixup" },
-
-    "global" => { default => 1, description => "global fixup" },
-
-    "modify" => { default => 0, description => "actually perform the fixups" },	    
-);
-
-my %options_short = (
-    "d" => "debug",
-    "?" => "help",
-    "v" => "verbose"
-);
-
-my $options_usage = "usage: winapi_fixup [--help] [<files>]\n";
-
-my $options = 'options'->new(\%options_long, \%options_short, $options_usage);
+use winapi_fixup_options qw($options);
 
 my $modules = 'modules'->new($options, $output, $wine_dir, $current_dir, \&file_type, "$winapi_check_dir/modules.dat");
 
@@ -91,6 +56,8 @@ foreach my $file (@c_files) {
 	$output->progress("$file: file $progress_current of $progress_max");
     }
 
+    my %documentation_line_used;
+
     my $found_function = sub {
 	my $function = shift;
 	
@@ -101,12 +68,12 @@ foreach my $file (@c_files) {
 	my $return_type = $function->return_type;
 	my $calling_convention = $function->calling_convention;
 	my $internal_name = $function->internal_name;
-	my @argument_types = @{$function->argument_types};
-	my @argument_names = @{$function->argument_names};
-	my @argument_documentations = @{$function->argument_documentations};
 	my $statements = $function->statements;
 
-	if($linkage eq "static" || ($linkage eq "" && !defined($statements))) {
+	if($linkage eq "static" ||
+	   ($linkage eq "extern" && !defined($statements)) ||
+	   ($linkage eq "" && !defined($statements)))
+	{
 	    return;
 	}
 
@@ -115,7 +82,12 @@ foreach my $file (@c_files) {
 	    return;
 	}
 
-	$output->prefix("$file: " . $function->prefix);
+	if($documentation_line_used{$documentation_line}) {
+	    $documentation = undef;
+	}
+	$documentation_line_used{$documentation_line}++;
+    
+	$output->prefix_callback(sub { return $function->prefix; });
 
 	my @module_ordinal_entries = ();
 	foreach my $entry2 ($function->get_all_module_ordinal) {
@@ -131,7 +103,7 @@ foreach my $file (@c_files) {
 
 	my $spec_modified = 0;
 
-	if($options->stub && $documentation) {
+	if($options->stub && defined($documentation)) {
 	    my $calling_convention16 = $function->calling_convention16;
 	    my $calling_convention32 = $function->calling_convention32;
 
@@ -170,6 +142,12 @@ foreach my $file (@c_files) {
 		foreach my $entry (@entries) {
 		    (my $external_name, my $module, my $ordinal) = @$entry;
 
+		    my $refargument_types = $function->argument_types;
+
+		    if(!defined($refargument_types)) {
+			next;
+		    }
+
 		    my $abort = 0;
 		    my $n;
 		    my @argument_kinds = map {
@@ -198,7 +176,7 @@ foreach my $file (@c_files) {
 			    $n++;
 			    "undef";
 			}
-		    } @argument_types;
+		    } @$refargument_types;
 
 		    my $substitute = {};
 		    $substitute->{search} = "^\\s*$ordinal\\s+stub\\s+$external_name\\s*(?:#.*?)?\$";
@@ -229,9 +207,9 @@ foreach my $file (@c_files) {
 	my $documentation_modified = 0;
 
 	if(!$spec_modified &&
-	   ($documentation && !$documentation_modified) &&
+	   (defined($documentation) && !$documentation_modified) &&
 	   ($options->documentation_name || $options->documentation_ordinal || 
-	    $options->documentation_missing)) 
+	    $options->documentation_missing))
 	{
 	    local $_;
 
@@ -337,6 +315,7 @@ foreach my $file (@c_files) {
 		    # $output->write("@external_names\n");
 		} else {
 		    $documentation_modified = 1;
+
 		    $substitute_line{$line3}{search} = $search;
 		    $substitute_line{$line3}{replace} = $replace;
 		    
@@ -345,7 +324,7 @@ foreach my $file (@c_files) {
 	}
 
 	if(!$spec_modified && !$documentation_modified &&
-	   $options->documentation_missing && $documentation)
+	   $options->documentation_missing && defined($documentation))
 	{
 	    my $part1;
 	    my $part2;
@@ -385,6 +364,8 @@ foreach my $file (@c_files) {
 		   !$win32api->is_function_stub_in_module($module2, $internal_name)) 
 		{
 		    if($line3 > 0) {
+			$documentation_modified = 1;
+
 			$part2 = $external_name2 . " " x (length($part2) - length($external_name2));
 			$insert_line{$line3} = "$part1$part2$part3\U$module2\E.$ordinal2$part4\n";
 		    } else {
@@ -395,6 +376,7 @@ foreach my $file (@c_files) {
 	}
 
 	if(!$documentation_modified && 
+	   defined($documentation) &&
 	   $options->documentation_wrong)
 	{
 	    my $line2 = $documentation_line - 1;
@@ -418,6 +400,8 @@ foreach my $file (@c_files) {
 		    }
 		    if(!$found) {
 			if(1) {
+			    $documentation_modified = 1;
+
 			    $delete_line{$line2} = "^\Q$_\E\$";
 			} else {
 			    $output->write("$external_name (\U$module\E.$ordinal) wrong (fixup not supported)\n");
@@ -427,24 +411,22 @@ foreach my $file (@c_files) {
 	    }
 	}
 
-	if(0) # !$spec_modified && !$documentation
+	if(!$spec_modified && !$documentation_modified && !defined($documentation))
 	{
-	    # FIXME: Not correct
-
-	    my $external_name;
-	    my $module;
-	    my $ordinal;
+	    my $insert = "";
 	    foreach my $winapi (@winapis) {
-		$external_name = ($winapi->function_external_name($internal_name) || $external_name);
-		$module = ($winapi->function_internal_module($internal_name) || $module);
-		$ordinal = ($winapi->function_internal_ordinal($internal_name) || $ordinal);
-		if(defined($external_name) || defined($module) || defined($ordinal)) { last; }
-	    }
+		my $external_name = $winapi->function_external_name($internal_name);
+		my $module = $winapi->function_internal_module($internal_name);
+		my $ordinal = $winapi->function_internal_ordinal($internal_name);
 
-	    if(defined($external_name) && defined($module) && defined($ordinal)) {
+		if(defined($external_name) && defined($module) && defined($ordinal)) {
+		    $insert .= " *\t\t$external_name (\U$module\E.$ordinal)\n";
+		}
+	    }
+	    if($insert) {
 		$insert_line{$function_line} = 
 		    "/" . "*" x 71 . "\n" .
-		    " *\t\t$external_name (\U$module\E.$ordinal)\n" .
+		    "$insert" .
 		    " */\n";
 	    }
 	}
@@ -457,7 +439,7 @@ foreach my $file (@c_files) {
 	my $argument = shift;
     };
 
-    winapi_parser::parse_c_file $options, $output, $file, $found_function, $found_preprocessor;
+    &winapi_parser::parse_c_file($options, $file, $found_function, $found_preprocessor);
 
     my $editor = sub {
 	local *IN = shift;
@@ -617,5 +599,3 @@ foreach my $file (@c_files) {
 }
 
 $output->hide_progress;
-
-
diff --git a/tools/winapi/winapi_fixup_options.pm b/tools/winapi/winapi_fixup_options.pm
new file mode 100644
index 0000000000000000000000000000000000000000..e2a26ddbab53053ee52e87672f1c84162f43ef52
--- /dev/null
+++ b/tools/winapi/winapi_fixup_options.pm
@@ -0,0 +1,48 @@
+package winapi_fixup_options;
+use base qw(options);
+
+use strict;
+
+use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
+require Exporter;
+
+@ISA = qw(Exporter);
+@EXPORT = qw();
+@EXPORT_OK = qw($options);
+
+use options qw($options &parse_comma_list);
+
+my %options_long = (
+    "debug" => { default => 0, description => "debug mode" },
+    "help" => { default => 0, description => "help mode" },
+    "verbose" => { default => 0, description => "verbose mode" },
+
+    "progress" => { default => 1, description => "show progress" },
+
+    "win16" => { default => 1, description => "Win16 fixup" },
+    "win32" => { default => 1, description => "Win32 fixup" },
+
+    "local" =>  { default => 1, description => "local fixup" },
+    "documentation" => { default => 1, parent => "local", description => "documentation fixup" },
+    "documentation-missing" => { default => 1, parent => "documentation", description => "documentation missing fixup" },
+    "documentation-name" => { default => 1, parent => "documentation", description => "documentation name fixup" },
+    "documentation-ordinal" => { default => 1, parent => "documentation", description => "documentation ordinal fixup" },
+    "documentation-wrong" => { default => 1, parent => "documentation", description => "documentation wrong fixup" },
+    "stub" => { default => 0, parent => "local", description => "stub fixup" },
+
+    "global" => { default => 1, description => "global fixup" },
+
+    "modify" => { default => 0, description => "actually perform the fixups" },	    
+);
+
+my %options_short = (
+    "d" => "debug",
+    "?" => "help",
+    "v" => "verbose"
+);
+
+my $options_usage = "usage: winapi_fixup [--help] [<files>]\n";
+
+$options = '_options'->new(\%options_long, \%options_short, $options_usage);
+
+1;
diff --git a/tools/winapi_check/winapi_check b/tools/winapi_check/winapi_check
index d79be72dcbac37f7b65909914a385d9dbb17ce5d..0c64082ee2ff2b8ead914ee8c3417863328d0a19 100755
--- a/tools/winapi_check/winapi_check
+++ b/tools/winapi_check/winapi_check
@@ -26,7 +26,7 @@ use config qw(
 );
 use modules;
 use nativeapi;
-use output;
+use output qw($output);
 use preprocessor;
 use util qw(&is_subset);
 use winapi;
@@ -34,21 +34,9 @@ use winapi_documentation;
 use winapi_function;
 use winapi_local;
 use winapi_global;
-use winapi_options;
+use winapi_check_options qw($options);
 use winapi_parser;
 
-my $output = 'output'->new;
-
-my $options = winapi_options->new($output, \@ARGV, $wine_dir);
-if(!defined($options)) {
-    $output->write("usage: winapi_check [--help] [<files>]\n");
-
-    exit 1;
-} elsif($options->help) {
-    $options->show_help;
-    exit;
-}
-
 my $modules = 'modules'->new($options, $output, $wine_dir, $current_dir, \&file_type, "$winapi_check_dir/modules.dat");
 
 my $win16api = 'winapi'->new($options, $output, "win16", "$winapi_check_dir/win16");
@@ -140,10 +128,12 @@ if($options->headers) {
 	my $found_function = sub {
 	    my $function = shift;
 
-	    $output->prefix($function->prefix);
+	    $output->prefix_callback(sub { return $function->prefix; });
 
 	    my $function_line = $function->function_line;
+	    my $linkage = $function->linkage;
 	    my $internal_name = $function->internal_name;
+	    my $external_name = $function->external_name;
 	    my $statements = $function->statements;
 
 	    if($options->headers_misplaced &&
@@ -154,7 +144,9 @@ if($options->headers) {
 		$output->write("declaration misplaced\n");
 	    }
 
-	    if(!defined($statements)) {
+	    if(defined($external_name) && !defined($statements) &&
+	       ($linkage eq "" || $linkage eq "extern")) 
+	    {
 		my $previous_function = $declared_functions{$internal_name};
 		if(!defined($previous_function)) {
 		    $declared_functions{$internal_name} = $function;
@@ -171,7 +163,7 @@ if($options->headers) {
 	    my $argument = shift;
 	};
 
-        winapi_parser::parse_c_file $options, $output, $file, $found_function, $found_preprocessor;
+        &winapi_parser::parse_c_file($options, $file, $found_function, $found_preprocessor);
     }
 }
 
@@ -182,6 +174,8 @@ foreach my $file (@c_files) {
     my %functions = ();
     my %includes = ();
 
+    $includes{$file}++;
+
     my $file_module16 = $modules->allowed_modules_in_file("$current_dir/$file");
     my $file_module32 = $modules->allowed_modules_in_file("$current_dir/$file");
 
@@ -198,7 +192,7 @@ foreach my $file (@c_files) {
     my $found_function = sub {
 	my $function = shift;
 
-	$output->prefix($function->prefix);
+	$output->prefix_callback(sub { return $function->prefix; });
 
 	my $internal_name = $function->internal_name;
 	$functions{$internal_name} = $function;
@@ -210,20 +204,44 @@ foreach my $file (@c_files) {
 	my $linkage = $function->linkage;
 	my $return_type = $function->return_type;
 	my $calling_convention = $function->calling_convention;
-	my @argument_types = @{$function->argument_types};
-	my @argument_names = @{$function->argument_names};
-	my @argument_documentations = @{$function->argument_documentations};
 	my $statements = $function->statements;
 
 	my $module16 = $function->module16;
 	my $module32 = $function->module32;
 
+	my $external_name = $function->external_name;
 	my $external_name16 = $function->external_name16;
 	my $external_name32 = $function->external_name32;
 
+	if(defined($external_name) && !defined($statements) && 
+	   ($linkage eq "" || $linkage eq "extern")) 
+	{
+	    my $previous_function = $declared_functions{$internal_name};
+	    if(!defined($previous_function)) {
+		$declared_functions{$internal_name} = $function;
+	    } else {
+		my $file = $previous_function->file;
+		my $function_line = $previous_function->function_line;
+
+		my $header = $file;
+		$header =~ s%^(include|$file_dir)/%%;
+		if($header !~ m%^msvcrt/% || $file_dir =~ m%^dlls/msvcrt%) {
+		    $output->write("duplicate declaration (first declaration at $file:$function_line)\n");
+		}
+	    }
+	}
+
 	foreach my $module ($function->modules) {
 	    $module2functions{$module}{$internal_name} = $function;
-	    for my $type ($return_type, @argument_types) {
+
+	    my @types = ($return_type);
+
+	    my $refargument_types = $function->argument_types;
+	    if(defined($refargument_types)) {
+		push @types, @$refargument_types;
+	    }
+
+	    for my $type (@types) {
 		$type_found{$module}{$type}++;
 	    }
 	}
@@ -240,16 +258,36 @@ foreach my $file (@c_files) {
 	    }
 	}
 
-	if($options->headers_needed && defined($declared_function)) {
+	if($options->headers && $options->headers_needed && 
+	   defined($declared_function) && defined($external_name) && 
+	   defined($statements))
+	{
 	    my $needed_include = $declared_function->file;
 
 	    if(!defined($includes{$needed_include})) {
 		my $header = $needed_include;
 		$header =~ s%^(include|$file_dir)/%%;
-		$output->write("prototype not included: #include \"$header\" is needed\n");
+		if($header !~ m%^msvcrt/% || $file_dir =~ m%^dlls/msvcrt%) {
+		    $output->write("prototype not included: #include \"$header\" is needed\n");
+		}
 	    }
 	}
 
+	if($options->local && $options->argument) {
+	    &winapi_local::check_function($function);
+	}
+	
+	if($options->local && $options->statements) {
+	    &winapi_local::check_statements(\%functions, $function);
+	}
+	
+	if($options->local && $options->documentation &&
+	   (defined($module16) || defined($module32)) &&
+	   $linkage ne "static" && ($linkage ne "" || defined($statements)))
+	{
+	    &winapi_documentation::check_documentation($function);
+	}
+
 	if(1) {
 	    # FIXME: Not correct
 	    if(defined($external_name16)) {
@@ -316,36 +354,9 @@ foreach my $file (@c_files) {
 		    }
 		}
 	    }
-
-	    if($options->local && $options->argument) {
-		if($options->win16 && $options->report_module($module16)) {
-		  winapi_local::check_function $options, $output,
-		    $return_type, $calling_convention, $external_name16, $internal_name, [@argument_types], $nativeapi, $win16api;
-		}	
-		if($options->win32 && $options->report_module($module32)) {
-		  winapi_local::check_function $options, $output,
-		    $return_type, $calling_convention, $external_name32, $internal_name, [@argument_types], $nativeapi, $win32api;
-		}
-	    }
-
-	    if($options->local && $options->statements) {
-		if($options->win16 && $options->report_module($module16)) {
-		  winapi_local::check_statements $options, $output, $win16api, \%functions, $function;
-		}
-
-		if($options->win32 && $options->report_module($module32)) {
-		  winapi_local::check_statements $options, $output, $win32api, \%functions, $function;
-		}
-	    }
-
-	    if($options->local && $options->documentation &&
-	       (defined($module16) || defined($module32)) &&
-	       $linkage ne "static" && ($linkage ne "" || defined($statements)))
-	    {
-	        winapi_documentation::check_documentation $options, $output, $win16api, $win32api, $modules, $function;
-	    }
-	    $output->prefix("");
 	}
+
+	$output->prefix("");
     };
 
     my $config = 0;
@@ -500,7 +511,7 @@ foreach my $file (@c_files) {
 	}
     };
   
-    winapi_parser::parse_c_file $options, $output, $file, $found_function, $found_preprocessor;
+    &winapi_parser::parse_c_file($options, $file, $found_function, $found_preprocessor);
     
     if($options->config_unnessary) {
 	if($config && $conditional == 0) {
@@ -508,7 +519,7 @@ foreach my $file (@c_files) {
 	}
     }
 
-    winapi_local::check_file $options, $output, $file, \%functions;
+    &winapi_local::check_file($file, \%functions);
 }
 
 $output->hide_progress;
@@ -565,7 +576,7 @@ if($options->declared) {
 }
 
 if($options->global) {
-    winapi_documentation::report_documentation $options, $output;
+    &winapi_documentation::report_documentation;
 
     if($options->headers_unused) {
 	foreach my $name (sort(keys(%include2info))) {
@@ -577,8 +588,7 @@ if($options->global) {
 	}
     }
 
-    winapi_global::check $options, $output, $win16api, $nativeapi, \%type_found if $options->win16;
-    winapi_global::check $options, $output, $win32api, $nativeapi, \%type_found if $options->win32;
+    &winapi_global::check(\%type_found);
 
     $modules->global_report;
     $nativeapi->global_report;
diff --git a/tools/winapi_check/winapi_documentation.pm b/tools/winapi_check/winapi_documentation.pm
index 36eb4386486aecd78b8b3e4a654f9b28502255ca..695f11a77fca4c908ecce4d213242a9cb45bc405 100644
--- a/tools/winapi_check/winapi_documentation.pm
+++ b/tools/winapi_check/winapi_documentation.pm
@@ -3,7 +3,11 @@ package winapi_documentation;
 use strict;
 
 use config qw($current_dir $wine_dir);
+use modules qw($modules);
 use nativeapi qw($nativeapi);
+use options qw($options);
+use output qw($output);
+use winapi qw($win16api $win32api @winapis);
 
 my %comment_width;
 my %comment_indent;
@@ -12,11 +16,6 @@ my %comment_spacing;
 sub check_documentation {
     local $_;
 
-    my $options = shift;
-    my $output = shift;
-    my $win16api = shift;
-    my $win32api = shift;
-    my $modules = shift;
     my $function = shift;
 
     my $file = $function->file;
@@ -29,7 +28,6 @@ sub check_documentation {
     my $ordinal32 = $function->ordinal32;
     my $documentation = $function->documentation;
     my $documentation_line = $function->documentation_line;
-    my @argument_documentations = @{$function->argument_documentations};
 
     my $documentation_error = 0;
     my $documentation_warning = 0;
@@ -159,12 +157,16 @@ sub check_documentation {
     }
 
     if($options->documentation_arguments) {
-	my $n = 0;
-	for my $argument_documentation (@argument_documentations) {
-	    $n++;
-	    if($argument_documentation ne "") {
-		if($argument_documentation !~ /^\/\*\s+\[(?:in|out|in\/out|\?\?\?)\].*?\*\/$/s) {
-		    $output->write("argument $n documentation: \\\n$argument_documentation\n");
+	my $refargument_documentations = $function->argument_documentations;
+
+	if(defined($refargument_documentations)) {
+	    my $n = 0;
+	    for my $argument_documentation (@$refargument_documentations) {
+		$n++;
+		if($argument_documentation ne "") {
+		    if($argument_documentation !~ /^\/\*\s+\[(?:in|out|in\/out|\?\?\?)\].*?\*\/$/s) {
+			$output->write("argument $n documentation: \\\n$argument_documentation\n");
+		    }
 		}
 	    }
 	}
@@ -172,9 +174,6 @@ sub check_documentation {
 }
 
 sub report_documentation {
-    my $options = shift;
-    my $output = shift;
-
     if($options->documentation_comment_indent) {
 	foreach my $indent (sort(keys(%comment_indent))) {
 	    my $count = $comment_indent{$indent};
diff --git a/tools/winapi_check/winapi_function.pm b/tools/winapi_check/winapi_function.pm
index a43ff57669eba0bbeef784cf91340dc9e2a2f8c6..6a3d0ec6572cb1e925d6e4c893b5cef57b87e8d3 100644
--- a/tools/winapi_check/winapi_function.pm
+++ b/tools/winapi_check/winapi_function.pm
@@ -74,13 +74,27 @@ sub _external_names {
     }
 }
 
+sub external_name { 
+    my $self = shift;
+
+    foreach my $winapi (@winapis) {
+	my $external_name = $self->_external_name($winapi, @_);
+
+	if(defined($external_name)) {
+	    return $external_name;
+	}
+    }
+
+    return undef;
+}
+
 sub external_name16 { my $self = shift; return $self->_external_name($win16api, @_); }
 sub external_name32 { my $self = shift; return $self->_external_name($win32api, @_); }
 
 sub external_names16 { my $self = shift; return $self->_external_names($win16api, @_); }
 sub external_names32 { my $self = shift; return $self->_external_names($win32api, @_); }
 
-sub external_names { my $self = shift; return ($self->external_names16,$self->external_names32); }
+sub external_names { my $self = shift; return ($self->external_names16, $self->external_names32); }
 
 ########################################################################
 # module
@@ -201,10 +215,14 @@ sub prefix {
     my $return_type = $self->return_type;
     my $internal_name = $self->internal_name;
     my $calling_convention = $self->calling_convention;
-    my @argument_types = @{$self->argument_types};
 
-    if($#argument_types < 0) {
-	@argument_types = ("void");
+    my $refargument_types = $self->argument_types;
+    my @argument_types = ();
+    if(defined($refargument_types)) {
+	@argument_types = @$refargument_types;
+	if($#argument_types < 0) {
+	    @argument_types = ("void");
+	}
     }
 
     my $prefix = "";
@@ -326,10 +344,14 @@ sub return_kind32 {
 sub _argument_kinds {   
     my $self = shift;
     my $winapi = shift;
-    my @argument_types = @{$self->argument_types};
+    my $refargument_types = $self->argument_types;
+
+    if(!defined($refargument_types)) {
+	return undef;
+    }
 
     my @argument_kinds;
-    foreach my $argument_type (@argument_types) {
+    foreach my $argument_type (@$refargument_types) {
 	my $argument_kind = $winapi->translate_argument($argument_type);
 
 	if(defined($argument_kind) && $argument_kind eq "longlong") {
diff --git a/tools/winapi_check/winapi_global.pm b/tools/winapi_check/winapi_global.pm
index 72490620c8b4b6a814e1e39ec96906b4bff16fdb..bb302e5141cfc268113266ede80cdb964671058e 100644
--- a/tools/winapi_check/winapi_global.pm
+++ b/tools/winapi_check/winapi_global.pm
@@ -1,12 +1,26 @@
 package winapi_global;
 
 use strict;
- 
+
+use nativeapi qw($nativeapi);
+use options qw($options);
+use output qw($output);
+use winapi qw($win16api $win32api @winapis);
+
 sub check {
-    my $options = shift;
-    my $output = shift;
+    my $type_found = shift;
+
+    if($options->win16) {
+	_check($win16api, $type_found);
+    }
+
+    if($options->win32) {
+	_check($win32api, $type_found);
+    }
+}
+
+sub _check {
     my $winapi = shift;
-    my $nativeapi = shift;
     my $type_found = shift;
 
     my $winver = $winapi->name;
diff --git a/tools/winapi_check/winapi_local.pm b/tools/winapi_check/winapi_local.pm
index 2c73d75af8c87d20c6194a5a21197eed78b5e05c..a4c523156a315ac001261cee306662b45fed222a 100644
--- a/tools/winapi_check/winapi_local.pm
+++ b/tools/winapi_check/winapi_local.pm
@@ -2,16 +2,51 @@ package winapi_local;
 
 use strict;
 
+use nativeapi qw($nativeapi);
+use options qw($options);
+use output qw($output);
+use winapi qw($win16api $win32api @winapis);
+
 sub check_function {
-    my $options = shift;
-    my $output = shift;
+    my $function = shift;
+
+    my $return_type = $function->return_type;
+    my $calling_convention = $function->calling_convention;
+    my $calling_convention16 = $function->calling_convention16;
+    my $calling_convention32 = $function->calling_convention32;
+    my $internal_name = $function->internal_name;
+    my $external_name16 = $function->external_name16;
+    my $external_name32 = $function->external_name32;
+    my $module16 = $function->module16;
+    my $module32 = $function->module32;
+    my $refargument_types = $function->argument_types;
+
+    if(!defined($refargument_types)) {
+	return;
+    }
+
+    if($options->win16 && $options->report_module($module16)) {
+	_check_function($return_type, 
+			$calling_convention, $external_name16, 
+			$internal_name, $refargument_types,
+			$win16api);
+    }
+
+    if($options->win32 && $options->report_module($module32)) {
+	_check_function($return_type, 
+			$calling_convention, $external_name32, 
+			$internal_name, $refargument_types,
+			$win32api);
+    }
+}
+
+sub _check_function {
     my $return_type = shift;
     my $calling_convention = shift;
     my $external_name = shift;
     my $internal_name = shift;
     my $refargument_types = shift;
     my @argument_types = @$refargument_types;
-    my $nativeapi = shift;
     my $winapi = shift;
 
     my $module = $winapi->function_internal_module($internal_name);
@@ -212,8 +247,22 @@ sub check_function {
 }
 
 sub check_statements {
-    my $options = shift;
-    my $output = shift;
+    my $functions = shift;
+    my $function = shift;
+
+    my $module16 = $function->module16;
+    my $module32 = $function->module32;
+
+    if($options->win16 && $options->report_module($module16)) {
+	_check_statements($win16api, $functions, $function);
+    }
+
+    if($options->win32 && $options->report_module($module32)) {
+	_check_statements($win16api, $functions, $function);
+    }
+}
+
+sub _check_statements {
     my $winapi = shift;
     my $functions = shift;
     my $function = shift;
@@ -288,8 +337,6 @@ sub check_statements {
 }
 
 sub check_file {
-    my $options = shift;
-    my $output = shift;
     my $file = shift;
     my $functions = shift;
 
diff --git a/tools/winapi_check/winapi_options.pm b/tools/winapi_check/winapi_options.pm
index 21b9f2a950ba1a88cf077bc1940af1f33eaa498b..73b617c138eb3d560ee43bd2ee6adf4d36d51cf7 100644
--- a/tools/winapi_check/winapi_options.pm
+++ b/tools/winapi_check/winapi_options.pm
@@ -2,6 +2,18 @@ package winapi_options;
 
 use strict;
 
+use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
+require Exporter;
+
+@ISA = qw(Exporter);
+@EXPORT = qw(&parse_comma_list);
+@EXPORT_OK = qw($options);
+
+use vars qw($options);
+
+use config qw($current_dir $wine_dir);
+use output qw($output);
+
 sub parser_comma_list {
     my $prefix = shift;
     my $value = shift;
@@ -138,12 +150,6 @@ sub new {
     my $self  = {};
     bless ($self, $class);
 
-    my $output = \${$self->{OUTPUT}};
-
-    $$output = shift;
-    my $refarguments = shift;
-    my $wine_dir = shift;
-
     $self->options_set("default");
 
     my $c_files = \@{$self->{C_FILES}};
@@ -160,7 +166,7 @@ sub new {
 	$$global = 0;
     }
 
-    while(defined($_ = shift @$refarguments)) {
+    while(defined($_ = shift @ARGV)) {
 	if(/^--(all|none)$/) {
 	    $self->options_set("$1");
 	    next;
@@ -185,7 +191,7 @@ sub new {
 		$name = $1;
 		$prefix = "no";
 		if(defined($value)) {
-		    $$output->write("options with prefix 'no' can't take parameters\n");
+		    $output->write("options with prefix 'no' can't take parameters\n");
 
 		    return undef;
 		}
@@ -258,12 +264,12 @@ sub new {
 	    $$module = { active => 1, filter => 1, hash => \%names };
 	}	
 	elsif(/^-(.*)$/) {
-	    $$output->write("unknown option: $_\n"); 
+	    $output->write("unknown option: $_\n"); 
 
 	    return undef;
 	} else {
 	    if(!-e $_) {
-		$$output->write("$_: no such file or directory\n");
+		$output->write("$_: no such file or directory\n");
 
 		return undef;
 	    }
@@ -329,6 +335,9 @@ sub new {
 	    }
 	} split(/\n/, `$h_command`));
     }
+
+    $options = $self;
+
     return $self;
 }
 
diff --git a/tools/winapi_check/winapi_parser.pm b/tools/winapi_check/winapi_parser.pm
index 8e99f839ab9f2fd55a06a132fff9e000f3d66be7..077ce10bae6967c22361c7f31cc69025b9b8035e 100644
--- a/tools/winapi_check/winapi_parser.pm
+++ b/tools/winapi_check/winapi_parser.pm
@@ -2,11 +2,11 @@ package winapi_parser;
 
 use strict;
 
+use output qw($output);
 use winapi_function;
 
 sub parse_c_file {
     my $options = shift;
-    my $output = shift;
     my $file = shift;
     my $function_found_callback = shift;
     my $preprocessor_found_callback = shift;
@@ -39,13 +39,17 @@ sub parse_c_file {
 	$argument_names = shift;
 	$argument_documentations = shift;
 
-	if($#$argument_names == -1) {
+	if(defined($argument_names) && defined($argument_types) &&
+	   $#$argument_names == -1)
+	{
 	    foreach my $n (0..$#$argument_types) {
 		push @$argument_names, "";
 	    }
 	}
 
-	if($#$argument_documentations == -1) {
+	if(defined($argument_documentations) &&
+	   $#$argument_documentations == -1)
+	{
 	    foreach my $n (0..$#$argument_documentations) {
 		push @$argument_documentations, "";
 	    }
@@ -69,9 +73,15 @@ sub parse_c_file {
 	$function->return_type($return_type); 
 	$function->calling_convention($calling_convention);
 	$function->internal_name($internal_name);
-	$function->argument_types([@$argument_types]);
-	$function->argument_names([@$argument_names]);
-	$function->argument_documentations([@$argument_documentations]);
+	if(defined($argument_types)) {
+	    $function->argument_types([@$argument_types]);
+	}
+	if(defined($argument_names)) {
+	    $function->argument_names([@$argument_names]);
+	}
+	if(defined($argument_documentations)) {
+	    $function->argument_documentations([@$argument_documentations]);
+	}
 	$function->statements($statements);
 
 	&$function_found_callback($function);
@@ -351,53 +361,89 @@ sub parse_c_file {
 		&$function_end;
 	    }
 	} elsif(/__ASM_GLOBAL_FUNC\(\s*(.*?)\s*,/s) {
+	    my @lines = split(/\n/, $&);
+	    my $function_line = $. - scalar(@lines) + 1;
+
 	    $_ = $'; $again = 1;
-	    my @arguments = ();
+
 	    &$function_begin($documentation_line, $documentation,
-			     $function_line, "", "void", "__asm", $1, \@arguments);
+			     $function_line, "", "void", "__asm", $1);
+	    $statements = "";
 	    &$function_end;
-	} elsif(/DC_(GET_X_Y|GET_VAL_16)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
+	} elsif(/DC_(GET_X_Y_16|GET_VAL_16)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s){ 
+	    my @lines = split(/\n/, $&);
+	    my $function_line = $. - scalar(@lines) + 1;
+
 	    $_ = $'; $again = 1;
+
+	    my $return16 = $2 . "16";
+	    my $name16 = $3 . "16";
+
+	    $return16 =~ s/^(COLORREF|DWORD)16$/$1/;
+
 	    my @arguments = ("HDC16");
 	    &$function_begin($documentation_line, $documentation,
-			     $function_line, "", $2, "WINAPI", $3, \@arguments);
+			     $function_line, "", $return16, "WINAPI", $name16, \@arguments);
+	    $statements = "";
 	    &$function_end;
-	} elsif(/DC_(GET_VAL)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,.*?\)/s) {
+	} elsif(/DC_(GET_VAL_32)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,.*?\)/s) {
+	    my @lines = split(/\n/, $&);
+	    my $function_line = $. - scalar(@lines) + 1;
+
 	    $_ = $'; $again = 1;
-	    my $return16 = $3 . "16";
-	    my $return32 = $3;
-	    my $name16 = $2 . "16";
-	    my $name32 = $2;
-	    my @arguments16 = ("HDC16");
-	    my @arguments32 = ("HDC");
 
-	    if($name16 eq "COLORREF16") { $name16 = "COLORREF"; }
+	    my $return32 = $2;
+	    my $name32 = $3;
+	    my @arguments32 = ("HDC");
 
-	    &$function_begin($documentation_line, $documentation,
-			     $function_line, "", $name16, "WINAPI", $return16, \@arguments16);
 	    &$function_end;
 	    &$function_begin($documentation_line, $documentation,
-			     $function_line, "", $name32, "WINAPI", $return32, \@arguments32);
+			     $function_line, "", $return32, "WINAPI", $name32, \@arguments32);
+	    $statements = "";
 	    &$function_end;
-	} elsif(/DC_(GET_VAL_EX)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
+	} elsif(/DC_(GET_VAL_EX_16)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
+	    my @lines = split(/\n/, $&);
+	    my $function_line = $. - scalar(@lines) + 1;
+
 	    $_ = $'; $again = 1;
+
 	    my @arguments16 = ("HDC16", "LP" . $5 . "16");
-	    my @arguments32 = ("HDC", "LP" . $5);
 	    &$function_begin($documentation_line, $documentation,
 			     $function_line, "", "BOOL16", "WINAPI", $2 . "16", \@arguments16);
+	    $statements = "";
 	    &$function_end;
+	} elsif(/DC_(GET_VAL_EX_32)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
+	    my @lines = split(/\n/, $&);
+	    my $function_line = $. - scalar(@lines) + 1;
+
+	    $_ = $'; $again = 1;
+
+	    my @arguments32 = ("HDC", "LP" . $5);
 	    &$function_begin($documentation_line, $documentation,
 			     $function_line, "", "BOOL", "WINAPI", $2, \@arguments32);
+	    $statements = "";
 	    &$function_end;
-	} elsif(/DC_(SET_MODE)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
+	} elsif(/DC_(SET_MODE_16)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
+	    my @lines = split(/\n/, $&);
+	    my $function_line = $. - scalar(@lines) + 1;
+
 	    $_ = $'; $again = 1;
+
 	    my @arguments16 = ("HDC16", "INT16");
-	    my @arguments32 = ("HDC", "INT");
 	    &$function_begin($documentation_line, $documentation,
 			     $function_line, "", "INT16", "WINAPI", $2 . "16", \@arguments16);
+	    $statements = "";
 	    &$function_end;
+	} elsif(/DC_(SET_MODE_32)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
+	    my @lines = split(/\n/, $&);
+	    my $function_line = $. - scalar(@lines) + 1;
+
+	    $_ = $'; $again = 1;
+
+	    my @arguments32 = ("HDC", "INT");
 	    &$function_begin($documentation_line, $documentation,
 			     $function_line, "", "INT", "WINAPI", $2, \@arguments32);
+	    $statements = "";
 	    &$function_end;
 	} elsif(/WAVEIN_SHORTCUT_0\s*\(\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
 	    $_ = $'; $again = 1;
@@ -405,27 +451,39 @@ sub parse_c_file {
 	    my @arguments32 = ("HWAVEIN");
 	    &$function_begin($documentation_line, $documentation,
 			     $function_line,  "", "UINT16", "WINAPI", "waveIn" . $1 . "16", \@arguments16);
+	    $statements = "";
 	    &$function_end;
 	    &$function_begin($documentation_line, $documentation,
 			     $function_line, "", "UINT", "WINAPI", "waveIn" . $1, \@arguments32);
+	    $statements = "";
 	    &$function_end;	    
 	} elsif(/WAVEOUT_SHORTCUT_0\s*\(\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
+	    my @lines = split(/\n/, $&);
+	    my $function_line = $. - scalar(@lines) + 1;
+
 	    $_ = $'; $again = 1;
+
 	    my @arguments16 = ("HWAVEOUT16");
 	    my @arguments32 = ("HWAVEOUT");
 	    &$function_begin($documentation_line, $documentation,
 			     $function_line, "", "UINT16", "WINAPI", "waveOut" . $1 . "16", \@arguments16);
+	    $statements = "";
 	    &$function_end;
 	    &$function_begin($documentation_line, $documentation,
 			     $function_line, "", "UINT", "WINAPI", "waveOut" . $1, \@arguments32);	    
 	    &$function_end;
 	} elsif(/WAVEOUT_SHORTCUT_(1|2)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
+	    my @lines = split(/\n/, $&);
+	    my $function_line = $. - scalar(@lines) + 1;
+
 	    $_ = $'; $again = 1;
+
 	    if($1 eq "1") {
 		my @arguments16 = ("HWAVEOUT16", $4);
 		my @arguments32 = ("HWAVEOUT", $4);
 		&$function_begin($documentation_line, $documentation,
 				 $function_line, "", "UINT16", "WINAPI", "waveOut" . $2 . "16", \@arguments16);
+		$statements = "";
 		&$function_end;
 		&$function_begin($documentation_line, $documentation,
 				 $function_line, "", "UINT", "WINAPI", "waveOut" . $2, \@arguments32);
@@ -435,6 +493,7 @@ sub parse_c_file {
 		my @arguments32 = ("UINT", $4);
 		&$function_begin($documentation_line, $documentation,
 				 $function_line, "", "UINT16", "WINAPI", "waveOut". $2 . "16", \@arguments16);
+		$statements = "";
 		&$function_end;
 		&$function_begin($documentation_line, $documentation, 
 				 $function_line, "", "UINT", "WINAPI", "waveOut" . $2, \@arguments32);