[glibmm/gmmproc-refactor] Added m4 macros implementations.



commit 84045ff835ad3d3a51a557c0c4cfef054a9ce7a9
Author: Krzesimir Nowak <qdlacz gmail com>
Date:   Sat Apr 7 16:23:17 2012 +0200

    Added m4 macros implementations.
    
    Some miscellaneous macros are still unwrapped. Also, this code will
    need review.

 tools/pm/Common/Output.pm                  | 1089 +---------------------------
 tools/pm/Common/Output/BoxedType.pm        |  237 ++++++
 tools/pm/Common/Output/BoxedTypeStatic.pm  |  188 +++++
 tools/pm/Common/Output/Ctor.pm             |  145 ++++
 tools/pm/Common/Output/Enum.pm             |  124 ++++
 tools/pm/Common/Output/GError.pm           |  127 ++++
 tools/pm/Common/Output/GObject.pm          |  502 +++++++++++++
 tools/pm/Common/Output/Generic.pm          |   55 ++
 tools/pm/Common/Output/Gobject.pm          |  461 ------------
 tools/pm/Common/Output/GtkObject.pm        |   26 +
 tools/pm/Common/Output/Interface.pm        |  378 ++++++++++
 tools/pm/Common/Output/Method.pm           |  183 +++++
 tools/pm/Common/Output/OpaqueCopyable.pm   |  188 +++++
 tools/pm/Common/Output/OpaqueRefcounted.pm |  191 +++++
 tools/pm/Common/Output/Property.pm         |   97 +++
 tools/pm/Common/Output/Shared.pm           |  548 ++++++++++++++-
 tools/pm/Common/Output/Signal.pm           |  359 +++++++++
 tools/pm/Common/Output/VFunc.pm            |  255 +++++++
 18 files changed, 3598 insertions(+), 1555 deletions(-)
---
diff --git a/tools/pm/Common/Output.pm b/tools/pm/Common/Output.pm
index e1a5ff0..200061d 100644
--- a/tools/pm/Common/Output.pm
+++ b/tools/pm/Common/Output.pm
@@ -1,6 +1,7 @@
-# Gtkmmproc Output module
+# -*- mode: perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# gmmproc - Common::Output module
 #
-# Copyright 2001 Free Software Foundation
+# Copyright 2012 glibmm development team
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -16,1076 +17,22 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 #
-package Output;
-use strict;
-use open IO => ":utf8";
-
-BEGIN { @Namespace::ISA=qw(main); }
-
-# $objOutputter new()
-sub new
-{
-  my ($m4path, $macrodirs) = @_;
-  my $self = {};
-  bless $self;
-
-  $$self{out} = [];
-
-  $$self{source} = "";
-  $$self{tmpdir} = File::Spec->tmpdir();
-  $$self{destdir} = "";
-  $$self{objDefsParser} = undef; # It will be set in set_defsparser()
-
-  $$self{m4path} = $m4path;
-  $$self{m4args} = "-I";
-  $$self{m4args} .= join(" -I", @$macrodirs);
-
-  return $self;
-}
-
-sub set_defsparser($$)
-{
-  my ($self, $objDefsParser) = @_;
-
-  $$self{objDefsParser} = $objDefsParser; #Remember it so that we can use it in our output methods.
-}
-
-sub m4args_append($$)
-{
-  my ($self, $str) = @_;
-  $$self{m4args} .= $str;
-}
-
-sub append($$)
-{
-  my ($self, $str) = @_;
-
-  push(@{$$self{out}}, $str);
-}
-
-# void output_wrap_failed($cname, $error)
-# Puts a comment in the header about the error during code-generation.
-sub output_wrap_failed($$$)
-{
-  my ($self, $cname, $error) = @_;
-
-  my $str = sprintf("//gtkmmproc error: %s : %s", $cname, $error);
-  print STDERR "Output.pm: $cname : $error\n";
-  $self->append($str);
-}
-
-sub error
-{
-  my $format=shift @_;
-  printf STDERR "Output.pm: $format",@_;
-}
-
-sub ifdef($$)
-{
-  my ($self, $ifdef) = @_;
-  if ($ifdef)
-  {
-    $self->append("\n#ifdef $ifdef\n");
-  }
-}
-
-sub endif($$)
-{
-  my ($self, $ifdef) = @_;
-  if ($ifdef)
-  {
-    $self->append("\n#endif // $ifdef\n");
-  }
-}
-
-### Convert _WRAP to a virtual
-# _VFUNC_H(signame,rettype,`<cppargs>')
-# _VFUNC_PH(gtkname,crettype,cargs and names)
-# void output_wrap_vfunc_h($filename, $line_num, $objCppfunc, $objCDefsFunc)
-sub output_wrap_vfunc_h($$$$$$)
-{
-  my ($self, $filename, $line_num, $objCppfunc, $objCDefsFunc, $ifdef) = @_;
-
-#Old code. We removed _VFUNC_H from the .m4 file
-#  my $str = sprintf("_VFUNC_H(%s,%s,\`%s\',%s)dnl\n",
-#    $$objCppfunc{name},
-#    $$objCppfunc{rettype},
-#    $objCppfunc->args_types_and_names(),
-#    $objCppfunc->get_is_const()
-#   );
-#  $self->append($str);
-
-  my $cppVfuncDecl = "virtual " . $$objCppfunc{rettype} . " " . $$objCppfunc{name} . "(" . $objCppfunc->args_types_and_names() . ")";
-  if($objCppfunc->get_is_const())
-  {
-    $cppVfuncDecl .= " const";
-  }
-
-  $self->ifdef($ifdef);
-  $self->append("  $cppVfuncDecl;\n");
-  $self->endif($ifdef);
-
-  #The default callback, which will call *_vfunc, which will then call the base default callback.
-  #Declares the callback in the private *Class class and sets it in the class_init function.
-
-  my $str = sprintf("_VFUNC_PH(%s,%s,\`%s\',%s)dnl\n",
-    $$objCDefsFunc{name},
-    $$objCDefsFunc{rettype},
-    $objCDefsFunc->args_types_and_names(),
-    $ifdef
-   );
-  $self->append($str);
-}
-
-# _VFUNC_CC(signame,gtkname,rettype,crettype,`<cppargs>',`<cargs>')
-sub output_wrap_vfunc_cc($$$$$$$)
-{
-  my ($self, $filename, $line_num, $objCppfunc, $objCFunc,
-      $custom_vfunc, $custom_vfunc_callback, $ifdef) = @_;
-
-  my $cname = $$objCFunc{name};
-
-  # e.g. Gtk::Button::draw_indicator:
-
-  #Use a different macro for Interfaces, to generate an extra convenience method.
-
-  if (!$custom_vfunc)
-  {
-    my $refreturn = "";
-    $refreturn = "refreturn" if($$objCppfunc{rettype_needs_ref});
-
-    my $str = sprintf("_VFUNC_CC(%s,%s,%s,%s,\`%s\',\`%s\',%s,%s,%s)dnl\n",
-      $$objCppfunc{name},
-      $cname,
-      $$objCppfunc{rettype},
-      $$objCFunc{rettype},
-      $objCppfunc->args_types_and_names(),
-      convert_args_cpp_to_c($objCppfunc, $objCFunc, 0, $line_num), #$objCppfunc->args_names_only(),
-      $objCppfunc->get_is_const(),
-      $refreturn,
-      $ifdef);
-
-    $self->append($str);
-  }
-
-  # e.g. Gtk::ButtonClass::draw_indicator():
-
-  if (!$custom_vfunc_callback)
-  {
-    my $refreturn_ctype = "";
-    $refreturn_ctype = "refreturn_ctype" if($$objCFunc{rettype_needs_ref});
-
-    my $str = sprintf("_VFUNC_PCC(%s,%s,%s,%s,\`%s\',\`%s\',\`%s\',%s,%s,%s)dnl\n",
-      $$objCppfunc{name},
-      $cname,
-      $$objCppfunc{rettype},
-      $$objCFunc{rettype},
-      $objCFunc->args_types_and_names(),
-      $objCFunc->args_names_only(),
-      convert_args_c_to_cpp($objCFunc, $objCppfunc, $line_num),
-      ${$objCFunc->get_param_names()}[0],
-      $refreturn_ctype,
-      $ifdef);
-
-    $self->append($str);
-  }
-}
-
-### Convert _WRAP to a signal
-# _SIGNAL_H(signame,rettype, ifdef, `<cppargs>')
-# _SIGNAL_PH(gtkname,crettype, ifdef, cargs and names)
-# void output_wrap_default_signal_handler_h($filename, $line_num, $objCppfunc, $objCDefsFunc, $ifdef. @args)
-sub output_wrap_default_signal_handler_h($$$$$$$)
-{
-  my ($self, $filename, $line_num, $objCppfunc, $objCDefsFunc, $ifdef) = @_;
-
-  my $str = sprintf("_SIGNAL_H(%s,%s,\`%s\',%s)dnl\n",
-    $$objCppfunc{name},
-    $$objCppfunc{rettype},
-    $objCppfunc->args_types_and_names(),
-    $ifdef
-   );
-  $self->append($str);
-
-
-  #The default callback, which will call *_impl, which will then call the base default callback.
-  #Declares the callback in the private *Class class and sets it in the class_init function.
-
-  $str = sprintf("_SIGNAL_PH(%s,%s,\`%s\',%s)dnl\n",
-    $$objCDefsFunc{name},
-    $$objCDefsFunc{rettype},
-    $objCDefsFunc->args_types_and_names(),
-    $ifdef
-   );
-  $self->append($str);
-}
-
-# _SIGNAL_CC(signame, gtkname, rettype, crettype,`<cppargs>',`<cargs>')
-sub output_wrap_default_signal_handler_cc($$$$$$$$$)
-{
-  my ($self, $filename, $line_num, $objCppfunc, $objDefsSignal, $bImplement, $bCustomCCallback, $bRefreturn, $ifdef) = @_;
-  my $cname = $$objDefsSignal{name};
-  # $cname = $1 if ($args[3] =~ /"(.*)"/); #TODO: What's this about?
-
-  # e.g. Gtk::Button::on_clicked:
-  if($bImplement eq 1)
-  {
-    my $refreturn = "";
-    $refreturn = "refreturn" if($bRefreturn eq 1);
-
-    my $str = sprintf("_SIGNAL_CC(%s,%s,%s,%s,\`%s\',\`%s\',%s,%s,%s)dnl\n",
-      $$objCppfunc{name},
-      $cname,
-      $$objCppfunc{rettype},
-      $$objDefsSignal{rettype},
-      $objCppfunc->args_types_and_names(),
-      convert_args_cpp_to_c($objCppfunc, $objDefsSignal, 0, $line_num), #$objCppfunc->args_names_only(),
-      $$objCppfunc{const},
-      $refreturn,
-      $ifdef);
-    $self->append($str);
-  }
-
-
-  # e.g. Gtk::ButtonClass::on_clicked():
-
-  #Callbacks always take the object instance as the first argument:
-#  my $arglist_names = "object";
-#  my $arglist_names_extra = $objDefsSignal->args_names_only();
-#  if ($arglist_names_extra)
-#  {
-#    $arglist_names .= ", ";
-#    $arglist_names .= $arglist_names_extra;
-#  }
-
-  if($bCustomCCallback ne 1)
-  {
-    my $str = sprintf("_SIGNAL_PCC(%s,%s,%s,%s,\`%s\',\`%s\',\`%s\',\`%s\',%s)dnl\n",
-      $$objCppfunc{name},
-      $cname,
-      $$objCppfunc{rettype},
-      $$objDefsSignal{rettype},
-      $objDefsSignal->args_types_and_names(),
-      $objDefsSignal->args_names_only(),
-      convert_args_c_to_cpp($objDefsSignal, $objCppfunc, $line_num),
-      ${$objDefsSignal->get_param_names()}[0],
-      $ifdef);
-    $self->append($str);
-  }
-}
-
-### Convert _WRAP to a method
-#  _METHOD(cppname,cname,cpprettype,crettype,arglist,cargs,const)
-#  void output_wrap_meth($filename, $line_num, $objCppFunc, $objCDefsFunc, $cppMethodDecl, $documentation, $ifdef)
-sub output_wrap_meth($$$$$$$)
-{
-  my ($self, $filename, $line_num, $objCppfunc, $objCDefsFunc, $cppMethodDecl, $documentation, $ifdef) = @_;
-  my $objDefsParser = $$self{objDefsParser};
-
-  my $cpp_param_names = $$objCppfunc{param_names};
-  my $cpp_param_types = $$objCppfunc{param_types};
-  my $cpp_param_mappings = $$objCppfunc{param_mappings};
-
-  my $num_args_list = $objCppfunc->get_num_possible_args_list();
-
-  my $output_var_name;
-  my $output_var_type;
-
-  if(defined($$cpp_param_mappings{"RET"}))
-  {
-    $output_var_name = $$cpp_param_names[$$cpp_param_mappings{"RET"}];
-    $output_var_type = $$cpp_param_types[$$cpp_param_mappings{"RET"}];
-  }
-
-  for(my $arg_list = 0; $arg_list < $num_args_list; $arg_list++)
-  {
-    # Allow the generated .h/.cc code to have an #ifndef around it, and add
-    # deprecation docs to the generated documentation.
-    my $deprecated = "";
-    if($$objCDefsFunc{deprecated})
-    {
-      $deprecated = "deprecated";
-    }
-
-    #Declaration:
-    if($deprecated ne "")
-    {
-      $self->append("\n_DEPRECATE_IFDEF_START");
-    }
-
-    if($arg_list == 0)
-    {
-      # Doxygen documentation before the method declaration:
-      $self->output_wrap_meth_docs_only($filename, $line_num, $documentation);
-    }
-    else
-    {
-      $self->append("\n\n  /// A $$objCppfunc{name}() convenience overload.\n");
-    }
-
-    $self->ifdef($ifdef);
-
-    $self->append("  " . $objCppfunc->get_declaration($arg_list));
-
-    $self->endif($ifdef);
-
-
-    if($deprecated ne "")
-    {
-      $self->append("\n_DEPRECATE_IFDEF_END\n");
-    }
-
-    my $refneeded = "";
-    if($$objCDefsFunc{rettype_needs_ref})
-    {
-      $refneeded = "refreturn"
-    }
-
-    my $errthrow = "";
-    if($$objCDefsFunc{throw_any_errors})
-    {
-      $errthrow = "errthrow"
-    }
-
-    my $constversion = ""; #Whether it is just a const overload (so it can reuse code)
-    if($$objCDefsFunc{constversion})
-    {
-      $constversion = "constversion"
-    }
-
-    #Implementation:
-    my $str;
-    if ($$objCppfunc{static}) {
-      $str = sprintf("_STATIC_METHOD(%s,%s,%s,%s,\`%s\',\`%s\',%s,%s,%s,%s,%s,%s,%s)dnl\n",
-        $$objCppfunc{name},
-        $$objCDefsFunc{c_name},
-        $$objCppfunc{rettype},
-        $objCDefsFunc->get_return_type_for_methods(),
-        $objCppfunc->args_types_and_names($arg_list),
-        convert_args_cpp_to_c($objCppfunc, $objCDefsFunc, 1, $line_num,
-          $errthrow, $arg_list), #1 means it's static, so it has 'object'.
-        $refneeded,
-        $errthrow,
-        $deprecated,
-        $ifdef,
-        $output_var_name,
-        $output_var_type,
-        $line_num
-        );
-    } else {
-      $str = sprintf("_METHOD(%s,%s,%s,%s,\`%s\',\`%s\',%s,%s,%s,%s,%s,\`%s\',%s,%s,%s,%s)dnl\n",
-        $$objCppfunc{name},
-        $$objCDefsFunc{c_name},
-        $$objCppfunc{rettype},
-        $objCDefsFunc->get_return_type_for_methods(),
-        $objCppfunc->args_types_and_names($arg_list),
-        convert_args_cpp_to_c($objCppfunc, $objCDefsFunc, 0, $line_num,
-          $errthrow, $arg_list),
-        $$objCppfunc{const},
-        $refneeded,
-        $errthrow,
-        $deprecated,
-        $constversion,
-        $objCppfunc->args_names_only($arg_list),
-        $ifdef,
-        $output_var_name,
-        $output_var_type,
-        $line_num
-        );
-    }
-    $self->append($str);
-  }
-}
-
-### Convert _WRAP to a method
-#  _METHOD(cppname,cname,cpprettype,crettype,arglist,cargs,const)
-#  void output_wrap_meth($filename, $line_num, $documentation)
-sub output_wrap_meth_docs_only($$$$)
-{
-  my ($self, $filename, $line_num, $documentation) = @_;
-  my $objDefsParser = $$self{objDefsParser};
-
-  # Doxygen documentation before the method declaration:
-  $self->append("\n${documentation}");
-}
-
-### Convert _WRAP_CTOR to a ctor
-#  _METHOD(cppname,cname,cpprettype,crettype,arglist,cargs,const)
-#  void output_wrap_ctor($filename, $line_num, $objCppFunc, $objCDefsFunc, $cppMethodDecl)
-sub output_wrap_ctor($$$$$)
-{
-  my ($self, $filename, $line_num, $objCppfunc, $objCDefsFunc, $cppMethodDecl) = @_;
-  my $objDefsParser = $$self{objDefsParser};
-
-  my $num_args_list = $objCppfunc->get_num_possible_args_list();
-
-  for(my $arg_list = 0; $arg_list < $num_args_list; $arg_list++)
-  {
-    if ($arg_list > 0)
-    {
-      $self->append("\n\n  /// A $$objCppfunc{name}() convenience overload.\n");
-    }
-
-    #Ctor Declaration:
-    #TODO: Add explicit.
-    $self->append("  explicit " . $objCppfunc->get_declaration($arg_list) . "\n");
-
-    #Implementation:
-    my $str = sprintf("_CTOR_IMPL(%s,%s,\`%s\',\`%s\')dnl\n",
-      $$objCppfunc{name},
-      $$objCDefsFunc{c_name},
-      $objCppfunc->args_types_and_names($arg_list),
-      get_ctor_properties($objCppfunc, $objCDefsFunc, $line_num, $arg_list)
-    );
-
-    $self->append($str);
-  }
-}
-
-sub output_wrap_create($$$)
-{
-  my ($self, $args_type_and_name_with_default_values, $objWrapParser) = @_;
-
-  #Re-use Function in a very hacky way, to separate the argument types_and_names.
-  my $fake_decl = "void fake_func(" . $args_type_and_name_with_default_values . ")";
-
-  my $objFunction = &Function::new($fake_decl, $objWrapParser);
-
-  my $num_args_list = $objFunction->get_num_possible_args_list();
-
-  for(my $arg_list = 0; $arg_list < $num_args_list; $arg_list++)
-  {
-    my $args_names_only = $objFunction->args_names_only($arg_list);
-    my $args_type_and_name_hpp =
-      $objFunction->args_types_and_names_with_default_values($arg_list);
-    my $args_type_and_name_cpp = $objFunction->args_types_and_names($arg_list);
-
-    if ($arg_list > 0) {
-      $self->append("\n  /// A create() convenience overload.");
-    }
-
-    my $str = sprintf("_CREATE_METHOD(\`%s\',\`%s\',\`%s\')dnl\n",
-                $args_type_and_name_hpp, , $args_type_and_name_cpp, $args_names_only);
-
-    $self->append($str)
-  }
-}
-
-# void output_wrap_sig_decl($filename, $line_num, $objCSignal, $objCppfunc, $signal_name, $bCustomCCallback)
-# custom_signalproxy_name is "" when no type conversion is required - a normal templates SignalProxy will be used instead.
-sub output_wrap_sig_decl($$$$$$$$)
-{
-  my ($self, $filename, $line_num, $objCSignal, $objCppfunc, $signal_name, $bCustomCCallback, $ifdef, $merge_doxycomment_with_previous) = @_;
-
-# _SIGNAL_PROXY(c_signal_name, c_return_type, `<c_arg_types_and_names>',
-#               cpp_signal_name, cpp_return_type, `<cpp_arg_types>',`<c_args_to_cpp>',
-#               refdoc_comment)
-
-  my $doxycomment = $objCppfunc->get_refdoc_comment();
-
-  # If there was already a previous doxygen comment, we want to merge this
-  # one with the previous so it is one big comment. If it were two separate
-  # comments, doxygen would ignore the first one. If
-  # $merge_doxycomment_with_previous is nonzero, the first comment is
-  # already open but not yet closed.
-  if($merge_doxycomment_with_previous)
-  {
-    # Strip leading whitespace
-    $doxycomment =~ s/^\s+//;
-    # We don't have something to add, so just close the comment.
-    if($doxycomment eq "")
-    {
-      $doxycomment = "   */";
-    }
-    else
-    {
-      # Append the new comment, but remove the first three leading characters
-      # (which are /**) that mark the beginning of the comment.
-      $doxycomment = substr($doxycomment, 3);
-      $doxycomment =~ s/^\s+//;
-      $doxycomment = "   " . $doxycomment;
-    }
-  }
-
-  my $str = sprintf("_SIGNAL_PROXY(%s,%s,\`%s\',%s,%s,\`%s\',\`%s\',\`%s\',\`%s\',%s)dnl\n",
-    $signal_name,
-    $$objCSignal{rettype},
-    $objCSignal->args_types_and_names_without_object(),
-    $$objCppfunc{name},
-    $$objCppfunc{rettype},
-    $objCppfunc->args_types_only(),
-    convert_args_c_to_cpp($objCSignal, $objCppfunc, $line_num),
-    $bCustomCCallback, #When this is true, it will not write the *_callback implementation for you.
-    $doxycomment,
-    $ifdef
-  );
-
-  $self->append($str);
-}
-
-# void output_wrap_enum($filename, $line_num, $cpp_type, $c_type, $comment, @flags)
-sub output_wrap_enum($$$$$$$)
-{
-  my ($self, $filename, $line_num, $cpp_type, $c_type, $comment, @flags) = @_;
-
-  my $objEnum = GtkDefs::lookup_enum($c_type);
-  if(!$objEnum)
-  {
-    $self->output_wrap_failed($c_type, "enum defs lookup failed.");
-    return;
-  }
-
-  $objEnum->beautify_values();
-
-  my $no_gtype = "";
-  my $elements = $objEnum->build_element_list(\ flags, \$no_gtype, "  ");
-
-  if(!$elements)
-  {
-    $self->output_wrap_failed($c_type, "unknown _WRAP_ENUM() flag");
-    return;
-  }
-
-  my $value_suffix = "Enum";
-  $value_suffix = "Flags" if($$objEnum{flags});
-
-  my $str = sprintf("_ENUM(%s,%s,%s,\`%s\',\`%s\',\`%s\')dnl\n",
-    $cpp_type,
-    $c_type,
-    $value_suffix,
-    $elements,
-    $no_gtype,
-    $comment
-  );
-
-  $self->append($str);
-}
-
-# void output_wrap_gerror($filename, $line_num, $cpp_type, $c_enum, $domain, @flags)
-sub output_wrap_gerror($$$$$$$)
-{
-  my ($self, $filename, $line_num, $cpp_type, $c_enum, $domain, @flags) = @_;
-
-  my $objDefsParser = $$self{objDefsParser};
-
-  my $objEnum = GtkDefs::lookup_enum($c_enum);
-  if(!$objEnum)
-  {
-    $self->output_wrap_failed($c_enum, "enum defs lookup failed.");
-    return;
-  }
-
-  # Shouldn't happen, and if it does, I'd like to know that.
-  warn if($$objEnum{flags});
-
-  $objEnum->beautify_values();
-
-  # cut off the module prefix, e.g. GDK_
-  my $prefix = $domain;
-  $prefix =~ s/^[^_]+_//;
-
-  # Chop off the domain prefix, because we put the enum into the class.
-  unshift(@flags, "s#^${prefix}_##");
 
-  my $no_gtype = "";
-  my $elements = $objEnum->build_element_list(\ flags, \$no_gtype, "    ");
+package Common::Output;
 
-  my $str = sprintf("_GERROR(%s,%s,%s,\`%s\',%s)dnl\n",
-    $cpp_type,
-    $c_enum,
-    $domain,
-    $elements,
-    $no_gtype
-  );
-
-  $self->append($str);
-}
-
-# _PROPERTY_PROXY(name, cpp_type)
-# void output_wrap_property($filename, $line_num, $name, $cpp_type)
-sub output_wrap_property($$$$$$)
-{
-  my ($self, $filename, $line_num, $name, $cpp_type, $c_class) = @_;
-
-  my $objDefsParser = $$self{objDefsParser};
-
-  my $objProperty = GtkDefs::lookup_property($c_class, $name);
-  if($objProperty eq 0) #If the lookup failed:
-  {
-    $self->output_wrap_failed($name, "property defs lookup failed.");
-  }
-  else
-  {
-    # We use a suffix to specify a particular Glib::PropertyProxy* class.
-    my $proxy_suffix = "";
-
-    # Read/Write:
-    if($objProperty->get_construct_only() eq 1)
-    {
-      # construct-only functions can be read, but not written.
-      $proxy_suffix = "_ReadOnly";
-
-      if($objProperty->get_readable() ne 1)
-      {
-        $self->output_wrap_failed($name, "attempt to wrap write-only and construct-only property.");
-        return;
-      }
-    }
-    elsif($objProperty->get_readable() ne 1)
-    {
-      $proxy_suffix = "_WriteOnly";
-    }
-    elsif($objProperty->get_writable() ne 1)
-    {
-       $proxy_suffix = "_ReadOnly";
-    }
-
-    # Convert - to _ so we can use it in C++ method and variable names:
-    my $name_underscored = $name;
-    $name_underscored =~ tr/-/_/;
-
-    # Get the property documentation, if any, and add m4 quotes.
-    my $documentation = $objProperty->get_docs();
-    add_m4_quotes(\$documentation) if ($documentation ne "");
-
-    my $str = sprintf("_PROPERTY_PROXY(%s,%s,%s,%s,`%s')dnl\n",
-      $name,
-      $name_underscored,
-      $cpp_type,
-      $proxy_suffix,
-      $documentation
-    );
-    $self->append($str);
-    $self->append("\n");
-
-    # If the property is not already read-only, and the property can be read,
-    # then add a second const accessor for a read-only propertyproxy:
-    if( ($proxy_suffix ne "_ReadOnly") && ($objProperty->get_readable()) )
-    {
-      my $str = sprintf("_PROPERTY_PROXY(%s,%s,%s,%s,`%s')dnl\n",
-        $name,
-        $name_underscored,
-        $cpp_type,
-        "_ReadOnly",
-        $documentation
-      );
-      $self->append($str);
-    }
-  }
-}
-
-sub add_m4_quotes($)
-{
-  my ($text) = @_;
-
-  # __BT__ and __FT__ are M4 macros defined in the base.m4 file that produce
-  # a "`" and a "'" resp. without M4 errors.
-  my %m4_quotes = (
-    "`" => "'__BT__`",
-    "'" => "'__FT__`",
-  );
-
-  $$text =~ s/([`'])/$m4_quotes{$1}/g;
-  $$text = "`" . $$text . "'";
-}
-
-# vpod output_temp_g1($filename, $section) e.g. output_temp_g1(button, gtk)
-sub output_temp_g1($$)
-{
-  my ($self, $section) = @_;
-
-  # Write out *.g1 temporary file
-  open(FILE, '>', "$$self{tmpdir}/gtkmmproc_$$.g1");  # $$ is the Process ID
-
-  print FILE "include(base.m4)dnl\n";
-
-  my $module = $section;
-  my $module_canonical = Util::string_canonical($module); #In case there is a / character in the module.
-  print FILE "_START($$self{source},$module,$module_canonical)dnl\n";
-  print FILE join("", @{$$self{out}});
-  print FILE "_END()\n";
-  close(FILE);
-}
-
-sub make_g2_from_g1($)
-{
-  my ($self) = @_;
-
-  # Execute m4 to get *.g2 file:
-  system("$$self{m4path} $$self{m4args} \"$$self{tmpdir}/gtkmmproc_$$.g1\" > \"$$self{tmpdir}/gtkmmproc_$$.g2\""); #"
-  return ($? >> 8);
-}
-
-# void write_sections_to_files()
-# This is where we snip the /tmp/gtkmmproc*.g2 file into sections (,h, .cc, _private.h)
-sub write_sections_to_files()
-{
-  my ($self) = @_;
-
-  my $fname_h  = "$$self{destdir}/$$self{source}.h";
-  my $fname_ph = "$$self{destdir}/private/$$self{source}_p.h";
-  my $fname_cc = "$$self{destdir}/$$self{source}.cc";
-
-  open(INPUT, '<', "$$self{tmpdir}/gtkmmproc_$$.g2"); # $$ is the process ID.
-
-  # open temporary file for each section
-  open(OUTPUT_H,  '>', "$fname_h.tmp");
-  open(OUTPUT_PH, '>', "$fname_ph.tmp");
-  open(OUTPUT_CC, '>', "$fname_cc.tmp");
-
-  my $oldfh = select(OUTPUT_H);
-  my $blank = 0;
-
-  while(<INPUT>)
-  {
-    # section switching
-    if(/^#S 0/) { select(OUTPUT_H);  next; }
-    if(/^#S 1/) { select(OUTPUT_PH); next; }
-    if(/^#S 2/) { select(OUTPUT_CC); next; }
-
-    # get rid of bogus blank lines
-    if(/^\s*$/) { ++$blank; } else { $blank = 0; }
-    next if($blank > 2);
-
-    print $_;
-  }
-
-  select($oldfh);
-  close(INPUT);
-  close(OUTPUT_H);
-  close(OUTPUT_PH);
-  close(OUTPUT_CC);
-
-  foreach($fname_h, $fname_ph, $fname_cc)
-  {
-    # overwrite the source file only if it has actually changed
-
-    # Win32 does fail at this, so we do the two steps separately:
-    #system("cmp -s '$_.tmp' '$_' || cp '$_.tmp' '$_'" ; rm -f '$_.tmp');
-
-    system("cmp -s '$_.tmp' '$_' || cp '$_.tmp' '$_'");
-    system("rm -f '$_.tmp'");
-  }
-}
-
-
-sub remove_temp_files($)
-{
-  my ($self) = @_;
-
-  system("rm -f \"$$self{tmpdir}/gtkmmproc_$$.g1\"");#"
-  system("rm -f \"$$self{tmpdir}/gtkmmproc_$$.g2\"");#"
-}
-
-
-
-# procedure for generating CONVERT macros
-# $string convert_args_cpp_to_c($objCppfunc, $objCDefsFunc, $static, $wrap_line_number,$automatic_error, $index = 0)
-# The optional index specifies which arg list out of the possible combination
-# of arguments based on whether any arguments are optional. index = 0 ==> all
-# the arguments.
-sub convert_args_cpp_to_c($$$$$)
-{
-  my ($objCppfunc, $objCDefsFunc, $static, $wrap_line_number, $automatic_error, $index) = @_;
-
-  $automatic_error = "" unless defined $automatic_error;
-  $index = 0 unless defined $index;
-
-  my $cpp_param_names = $$objCppfunc{param_names};
-  my $cpp_param_types = $$objCppfunc{param_types};
-  my $cpp_param_optional = $$objCppfunc{param_optional};
-  my $cpp_param_mappings = $$objCppfunc{param_mappings};
-  my $c_param_types = $$objCDefsFunc{param_types};
-  my $c_param_names = $$objCDefsFunc{param_names};
-
-  my @result;
-
-  my $num_c_args_expected = scalar(@{$c_param_types});
-  if( !($static) ) { $num_c_args_expected--; } #The cpp method will need an Object* paramater at the start.
-
-  my $num_cpp_args = scalar(@{$cpp_param_types});
-
-  my $has_output_param = 0;
-  my $output_param_index;
-
-  # See if there is an output parameter.  If so, temporarily decrement the
-  # number of C++ arguments so that the possible GError addition works and
-  # note the existence.
-  if(defined($$cpp_param_mappings{"RET"}))
-  {
-    $num_cpp_args--;
-    $has_output_param = 1;
-    $output_param_index = $$cpp_param_mappings{"RET"};
-  }
-
-  # add implicit last error parameter;
-  if ( $automatic_error ne "" &&
-       $num_cpp_args == ($num_c_args_expected - 1) &&
-       ${$c_param_types}[-1] eq "GError**" )
-  {
-    $num_cpp_args++;
-    $cpp_param_names = [ {$cpp_param_names},"gerror"];
-    $cpp_param_types = [ {$cpp_param_types},"GError*&"];
-    $cpp_param_optional = [ {$cpp_param_optional}, 0];
-
-    # Map from the C gerror param name to the newly added C++ param index.
-    # The correct C++ index to map to (from the C name) depends on if there
-    # is an output parameter since it will be readded.
-    my $cpp_index = $num_cpp_args - 1;
-    $cpp_index++ if($has_output_param);
-    $$cpp_param_mappings{ $c_param_names[$num_c_args_expected]} = $cpp_index;
-  }
-
-  if ( $num_cpp_args != $num_c_args_expected )
-  {
-    Output::error( "convert_args_cpp_to_c(): Incorrect number of arguments. (%d != %d)\n",
-             $num_cpp_args,
-             $num_c_args_expected );
-    $objCppfunc->dump();
-    $objCDefsFunc->dump();
-
-    return "";
-  }
-
-  # If there is an output variable it must be processed so re-increment (now)
-  # the number of C++ arguments.
-  $num_cpp_args++ if($has_output_param);
-
-  # Get the desired argument list combination.
-  my $possible_arg_list = $$objCppfunc{possible_args_list}[$index];
-
-  # Loop through the parameters:
-  my $i;
-  my $cpp_param_max = $num_cpp_args;
-  # if( !($static) ) { $cpp_param_max++; }
-
-  for ($i = 0; $i < $cpp_param_max; $i++)
-  {
-    # Skip the output parameter because it is handled in output_wrap_meth().
-    next if($has_output_param && $i == $output_param_index);
-
-    #index of C parameter:
-    my $iCParam = $i;
-    if( !($static) ) { $iCParam++; }
-
-    # Account for a possible C++ output param in the C++ arg list.
-    $iCParam-- if($has_output_param && $i > $output_param_index);
-
-    my $c_param_name = @$c_param_names[$iCParam];
-    my $cpp_param_index = $i;
-    $cpp_param_index = $$cpp_param_mappings{$c_param_name} if(defined($$cpp_param_mappings{$c_param_name}));
-
-    my $cppParamType = $$cpp_param_types[$cpp_param_index];
-    $cppParamType =~ s/ &/&/g; #Remove space between type and &
-    $cppParamType =~ s/ \*/*/g; #Remove space between type and *
-
-    my $cppParamName = $$cpp_param_names[$cpp_param_index];
-    my $cParamType = $$c_param_types[$iCParam];
-
-    if(!($possible_arg_list =~ /\b$cpp_param_index\b/))
-    {
-      # If the C++ index is not found in the list of desired parameters, pass
-      # NULL to the C func unless the param is not optional (applies to a
-      # possibly added GError parameter).
-      if ($$cpp_param_optional[$cpp_param_index])
-      {
-        push(@result, "0");
-        next;
-      }
-    }
-
-    if ($cppParamType ne $cParamType) #If a type conversion is needed.
-    {
-
-
-      push(@result, sprintf("_CONVERT(%s,%s,%s,%s)",
-                  $cppParamType,
-                  $cParamType,
-                  $cppParamName,
-                  $wrap_line_number) );
-    }
-    else
-    {
-      push(@result, $cppParamName);
-    }
-  }
-
-  return join(", ", @result);
-}
-
-# procedure for generating CONVERT macros
-# Ignores the first C 'self' argument.
-# $string convert_args_c_to_cpp($objCDefsFunc, $objCppFunc, $wrap_line_number)
-sub convert_args_c_to_cpp($$$)
-{
-  my ($objCDefsFunc, $objCppfunc, $wrap_line_number) = @_;
-
-  my $cpp_param_types = $$objCppfunc{param_types};
-  my $c_param_types = $$objCDefsFunc{param_types};
-  my $c_param_names = $$objCDefsFunc{param_names};
-
-  my @result;
-
-  my $num_c_args = scalar(@{$c_param_types});
-
-  my $num_cpp_args = scalar(@{$cpp_param_types});
-
-  if ( ($num_cpp_args + 1) !=  $num_c_args )
-  {
-    Output::error( "convert_args_c_to_cpp(): Incorrect number of arguments. (%d != %d)\n",
-             $num_cpp_args + 1,
-             $num_c_args);
-    $objCppfunc->dump();
-    $objCDefsFunc->dump();
-
-    return "";
-  }
-
-
-  # Loop through the c parameters:
- my $i;
- my $c_param_max = $num_c_args;
-
- for ($i = 1; $i < $c_param_max; $i++)
- {
-   #index of C parameter:
-   my $iCppParam = $i - 1;
-
-   my $cppParamType = $$cpp_param_types[$iCppParam];
-   $cppParamType =~ s/ &/&/g; #Remove space between type and &.
-   $cppParamType =~ s/ \*/*/g; #Remove space between type and *
-
-   my $cParamName = $$c_param_names[$i];
-   my $cParamType = $$c_param_types[$i];
-
-   if ($cParamType ne $cppParamType) #If a type conversion is needed.
-   {
-     push(@result, sprintf("_CONVERT(%s,%s,%s,%s)\n",
-                  $cParamType,
-                  $cppParamType,
-                  $cParamName,
-                  $wrap_line_number) );
-    }
-    else
-    {
-      push(@result, $cParamName);
-    }
-  }
-
-  return join(", ",@result);
-}
-
-
-# generates the XXX in g_object_new(get_type(), XXX): A list of property names and values.
-# Uses the cpp arg name as the property name.
-# The optional index specifies which arg list out of the possible combination
-# of arguments based on whether any arguments are optional. index = 0 ==> all
-# the arguments.
-# $string get_ctor_properties($objCppfunc, $objCDefsFunc, $wrap_line_number, $index = 0)
-sub get_ctor_properties($$$$$)
-{
-  my ($objCppfunc, $objCDefsFunc, $wrap_line_number, $index) = @_;
-
-  $index = 0 unless defined $index;
-
-  my $cpp_param_names = $$objCppfunc{param_names};
-  my $cpp_param_types = $$objCppfunc{param_types};
-  my $cpp_param_optional = $$objCppfunc{param_optional};
-  my $cpp_param_mappings = $$objCppfunc{param_mappings};
-  my $c_param_types = $$objCDefsFunc{param_types};
-  my $c_param_names = $$objCDefsFunc{param_names};
-
-  my @result;
-
-  my $num_args = scalar(@{$c_param_types});
-
-  my $num_cpp_args = scalar(@{$cpp_param_types});
-  if ( $num_cpp_args != $num_args )
-  {
-    Output::error("get_ctor_properties(): Incorrect number of arguments. (%d != %d)\n",
-             $num_cpp_args,
-             $num_args );
-    return "";
-  }
-
-
-  # Get the desired argument list combination.
-  my $possible_arg_list = $$objCppfunc{possible_args_list}[$index];
-
-  # Loop through the parameters:
-  my $i = 0;
-
-  for ($i = 0; $i < $num_args; $i++)
-  {
-    my $c_param_name = @$c_param_names[$i];
-    my $cpp_param_index = $i;
-    $cpp_param_index = $$cpp_param_mappings{$c_param_name} if(defined($$cpp_param_mappings{$c_param_name}));
-
-    my $cppParamType = $$cpp_param_types[$cpp_param_index];
-    $cppParamType =~ s/ &/&/g; #Remove space between type and &
-    $cppParamType =~ s/ \*/*/g; #Remove space between type and *
-
-    my $cppParamName = $$cpp_param_names[$cpp_param_index];
-    my $cParamType = $$c_param_types[$i];
-
-    # Property name:
-    push(@result, "\"" . $cppParamName . "\"");
-
-    if(!($possible_arg_list =~ /\b$cpp_param_index\b/))
-    {
-      # If the C++ index is not found in the list of desired parameters, pass
-      # NULL to the C func unless the param is not optional.
-      if ($$cpp_param_optional[$cpp_param_index])
-      {
-        push(@result, "0");
-        next;
-      }
-    }
-
-   # C property value:
-    if ($cppParamType ne $cParamType) #If a type conversion is needed.
-    {
-      push(@result, sprintf("_CONVERT(%s,%s,%s,%s)",
-                  $cppParamType,
-                  $cParamType,
-                  $cppParamName,
-                  $wrap_line_number) );
-    }
-    else
-    {
-      push(@result, $cppParamName);
-    }
-  }
-
-  return join(", ", @result);
-}
-
-### Convert _WRAP to a corba method
-# _CORBA_METHOD(retype, method_name,args, arg_names_only) - implemented in libbonobomm.
-#  void output_wrap_corba_method($filename, $line_num, $objCppFunc)
-sub output_wrap_corba_method($$$$)
-{
-  my ($self, $filename, $line_num, $objCppfunc) = @_;
-
-  my $str = sprintf("_CORBA_METHOD(%s,%s,\`%s\',\`%s\')dnl\n",
-      $$objCppfunc{rettype},
-      $$objCppfunc{name},
-      $objCppfunc->args_types_and_names(),
-      $objCppfunc->args_names_only()
-   );
-
-  $self->append($str);
-}
-
-sub output_implements_interface($$)
-{
-  my ($self, $interface, $ifdef) = @_;
-
-  my $str = sprintf("_IMPLEMENTS_INTERFACE_CC(%s, %s)dnl\n",
-    $interface,
-    $ifdef);
-
-  $self->append($str);
-}
+use strict;
+use warnings;
+
+use Common::Output::BoxedTypeStatic;
+use Common::Output::BoxedType;
+use Common::Output::Enum;
+use Common::Output::Generic;
+use Common::Output::GError;
+use Common::Output::GObject;
+use Common::Output::GtkObject;
+use Common::Output::Interface;
+use Common::Output::OpaqueCopyable;
+use Common::Output::OpaqueRefcounted;
+use Common::Output::VFunc;
 
 1; # indicate proper module load.
diff --git a/tools/pm/Common/Output/BoxedType.pm b/tools/pm/Common/Output/BoxedType.pm
new file mode 100644
index 0000000..cefa3ee
--- /dev/null
+++ b/tools/pm/Common/Output/BoxedType.pm
@@ -0,0 +1,237 @@
+# -*- mode: perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# gmmproc - Common::Output::BoxedType module
+#
+# Copyright 2012 glibmm development team
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+#
+
+package Common::Output::BoxedType;
+
+use strict;
+use warnings;
+
+sub nl
+{
+  return Common::Output::Shared::nl @_;
+}
+
+sub _output_h_before_first_namespace ($$$)
+{
+  my ($wrap_parser, $c_type, $cpp_type) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $variable = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::CUSTOM_STRUCT_PROTOTYPE;
+  my $conditional = Common::Output::Shared::generate_conditional $wrap_parser;
+  my $code_string = nl (Common::Output::Shared::doxy_skip_begin) .
+                    nl ('extern "C" { typedef struct _' . $c_type . ' ' . $c_type . '; }') .
+                    nl (Common::Output::Shared::doxy_skip_end);
+  my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::H_BEFORE_FIRST_NAMESPACE;
+
+  $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+  $section_manager->append_conditional_to_section ($conditional, $section);
+  $section_manager->set_variable_for_conditional ($variable, $conditional);
+}
+
+sub _output_h_in_class ($$$)
+{
+  my ($wrap_parser, $c_type, $cpp_type) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $main_section = $wrap_parser->get_main_section;
+  my $code_string = nl ('public:') .
+                    nl (Common::Output::Shared::doxy_skip_begin) .
+                    nl ('  typedef ' . $cpp_type . 'CppObjectType;') .
+                    nl ('  typedef ' . $c_type . 'BaseObjectType;') .
+                    nl () .
+                    nl (  'static GType get_type() G_GNUC_CONST;') .
+                    nl (Common::Output::Shared::doxy_skip_end) .
+                    nl ();
+
+  $section_manager->push_section ($main_section);
+  $section_manager->append_string ($code_string);
+
+  my $conditional = Common::Output::Shared::default_ctor_proto $wrap_parser, $cpp_type;
+  my $copy_proto = 'const';
+  my $reinterpret = 0;
+  my $definitions = 1;
+  my $virtual_dtor = 0;
+
+  $section_manager->append_conditional ($conditional);
+  $code_string = nl () .
+                 nl ('explicit ' . $cpp_type . '(' . $c_type . '* gobject, bool make_a_copy = true);') .
+                 nl () .
+                 nl (Common::Output::Shared::copy_protos_str $cpp_type) .
+                 nl () .
+                 nl (Common::Output::Shared::dtor_proto_str $cpp_type, $virtual_dtor) .
+                 nl () .
+                 nl ('  void swap(' . $cpp_type . '& other);') .
+                 nl () .
+                 nl (Common::Output::Shared::gobj_protos_str $c_type, $copy_proto, $reinterpret, $definitions) .
+                 nl () .
+                 nl ('protected:') .
+                 nl ('  ' . $c_type . '* gobject_;') .
+                 nl () .
+                 nl ('private:');
+  $section_manager->append_string ($code_string);
+  $section_manager->pop_entry;
+}
+
+sub _output_h_after_first_namespace ($$$)
+{
+  my ($wrap_parser, $c_type, $cpp_type) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+  my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::H_AFTER_FIRST_NAMESPACE;
+  my $code_string = nl (Common::Output::Shared::open_namespaces $wrap_parser) .
+                    nl () .
+                    nl ('/** @relates ' . $full_cpp_type) .
+                    nl (' *') .
+                    nl (' * @param lhs The left-hand side') .
+                    nl (' * @param rhs The right-hand side') .
+                    nl (' */') .
+                    nl ('inline void swap(' . $cpp_type . '& lhs, ' . $cpp_type . '& rhs)') .
+                    nl ('{ lhs.swap(rhs); }') .
+                    nl () .
+                    nl (Common::Output::Shared::close_namespaces $wrap_parser) .
+                    nl () .
+                    nl ('namespace Glib') .
+                    nl ('{') .
+                    nl ();
+
+  $section_manager->push_section ($section);
+  $section_manager->append_string ($code_string);
+
+  my $result_type = 'plain';
+  my $take_copy_by_default = 'no';
+  my $open_glib_namespace = 0;
+  my $const_function = 0;
+  my $conditional = Common::Output::Shared::wrap_proto $wrap_parser, $c_type, $result_type, $take_copy_by_default, $open_glib_namespace, $const_function;
+
+  $section_manager->append_conditional ($conditional);
+  $code_string = nl (Common::Output::Shared::doxy_skip_begin) .
+                 nl ('template <>') .
+                 nl ('class Value< ' . $full_cpp_type . ' > : public Glib::Value_Boxed< ' . $full_cpp_type . ' >') .
+                 nl ('{};') .
+                 nl (Common::Output::Shared::doxy_skip_end) .
+                 nl () .
+                 nl ('} // namespace Glib');
+  $section_manager->append_string ($code_string);
+  $section_manager->pop_entry;
+}
+
+sub _output_cc ($$$$$$$)
+{
+  my ($wrap_parser, $c_type, $cpp_type, $get_type_func, $new_func, $copy_func, $free_func) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $prefix = Common::Output::Shared::get_var_prefix $wrap_parser;
+  my $variable = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::NO_WRAP_FUNCTION;
+  my $conditional = Common::Output::Shared::generate_conditional $wrap_parser;
+  my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+  my $code_string = nl ('namespace Glib') .
+                    nl ('{') .
+                    nl () .
+                    nl ($full_cpp_type . ' wrap(' . $c_type . '* object, bool take_copy)') .
+                    nl ('{') .
+                    nl ('  return ' . $full_cpp_type . '(object, take_copy);') .
+                    nl ('}') .
+                    nl () .
+                    nl ('} // namespace Glib') .
+                    nl ();
+  my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_END;
+
+  $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+  $section_manager->push_section ($section);
+  $section_manager->append_conditional ($conditional);
+  $section_manager->set_variable_for_conditional ($variable, $conditional);
+  $code_string = nl (Common::Output::Shared::open_namespaces $wrap_parser) .
+                 nl ('// static') .
+                 nl ('GType ' . $cpp_type . '::get_type()') .
+                 nl ('{') .
+                 nl ('  return ' . $get_type_func . '();') .
+                 nl ('}') .
+                 nl ();
+  $section_manager->append_string ($code_string);
+  $variable = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::CUSTOM_DEFAULT_CTOR;
+  $conditional = Common::Output::Shared::generate_conditional $wrap_parser;
+  $code_string = nl($cpp_type . '::' . $cpp_type . '()') .
+                 nl(':');
+  if (defined $new_func and $new_func != '' and $new_func != 'NONE')
+  {
+    $code_string += nl ('gobject_ (' . $new_func . '())');
+  }
+  else
+  {
+    $code_string += nl ('gobject_ (0) // Allows creation of invalid wrapper, e.g. for output arguments to methods.');
+  }
+  $code_string += nl ('{}');
+  $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+  $section_manager->append_conditional ($conditional);
+  $section_manager->set_variable_for_conditional ($variable, $conditional);
+  $code_string = nl ($cpp_type . '::' . $cpp_type . '(const ' . $cpp_type . '& other)') .
+                 nl (':') .
+                 nl ('  gobject_ ((other.gobject_) ? ' . $copy_func . '(other.gobject_) : 0)') .
+                 nl ('{}') .
+                 nl () .
+                 nl ($cpp_type . '::' . $cpp_type . '(' . $c_type . '* gobject, bool make_a_copy)') .
+                 nl (':') .
+                 nl ('// For BoxedType wrappers, make_a_copy is true by default. The static') .
+                 nl ('// BoxedTyoe wrappers always take a copy, thus make_a_copy = true') .
+                 nl ('// ensures identical behaviour if the default argument is used.') .
+                 nl ('  gobject_ ((make_a_copy && gobject) ? ' . $copy_func . '(gobject) : gobject)') .
+                 nl ('{}') .
+                 nl () .
+                 nl ($cpp_type . '& ' . $cpp_type . '::operator=(const ' . $cpp_type . '& other)') .
+                 nl ('{') .
+                 nl ('  ' . $cpp_type . ' temp (other);') .
+                 nl ('  swap(temp);') .
+                 nl ('  return *this;') .
+                 nl ('}') .
+                 nl () .
+                 nl ($cpp_type . '::~' . $cpp_type . '()') .
+                 nl ('{') .
+                 nl ('  if (gobject_)') .
+                 nl ('    ' . $free_func . '(gobject_);') .
+                 nl ('}') .
+                 nl () .
+                 nl ('void ' . $cpp_type . '::swap(' . $cpp_type . '& other)') .
+                 nl ('{') .
+                 nl ('  ' . $c_type . '* const temp = gobject_;') .
+                 nl ('  gobject_ = other.gobject_;') .
+                 nl ('  other.gobject_ = temp;') .
+                 nl ('}') .
+                 nl () .
+                 nl ($c_type . '* ' . $cpp_type . '::gobj_copy() const') .
+                 nl ('{') .
+                 nl ('  return ' . $copy_func . '(gobject_);') .
+                 nl ('}') .
+                 nl ();
+  $section_manager->append_string ($code_string);
+  $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_NAMESPACE;
+  $section_manager->append_section ($section);
+  $code_string = nl (Common::Output::Shared::close_namespaces $wrap_parser);
+  $section_manager->append_string ($code_string);
+  $section_manager->pop_entry;
+}
+
+sub output ($)
+{
+  my ($wrap_parser, $c_type, $cpp_type, $get_type_func, $new_func, $copy_func, $free_func) = @_;
+
+  _output_h_before_first_namespace $wrap_parser, $c_type, $cpp_type;
+  _output_h_in_class $wrap_parser, $c_type, $cpp_type;
+  _output_h_after_first_namespace $wrap_parser, $c_type, $cpp_type;
+  _output_cc $wrap_parser, $c_type, $cpp_type, $get_type_func, $new_func, $copy_func, $free_func;
+}
+
+1; # indicate proper module load.
diff --git a/tools/pm/Common/Output/BoxedTypeStatic.pm b/tools/pm/Common/Output/BoxedTypeStatic.pm
new file mode 100644
index 0000000..ef9c565
--- /dev/null
+++ b/tools/pm/Common/Output/BoxedTypeStatic.pm
@@ -0,0 +1,188 @@
+# -*- mode: perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# gmmproc - Common::Output::BoxedTypeStatic module
+#
+# Copyright 2012 glibmm development team
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+#
+
+package Common::Output::BoxedTypeStatic;
+
+use strict;
+use warnings;
+
+use Common::Output::Shared;
+
+sub nl
+{
+  return Common::Output::Shared::nl @_;
+}
+
+sub _output_h_in_class ($$$)
+{
+  my ($wrap_parser, $c_type, $cpp_type) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $code_string = nl ('public:') .
+                    nl (Common::Output::Shared::doxy_skip_begin) .
+                    nl ('  typedef ' . $cpp_type . 'CppObjectType;') .
+                    nl ('  typedef ' . $c_type . 'BaseObjectType;') .
+                    nl () .
+                    nl ('  static GType get_type() G_GNUC_CONST') .
+                    nl (Common::Output::Shared::doxy_skip_end) .
+                    nl ();
+  my $main_section = $wrap_parser->get_main_section;
+
+  $section_manager->push_section ($main_section);
+  $section_manager->append_string ($code_string);
+
+  my $conditional = Common::Output::Shared::default_ctor_proto $wrap_parser, $cpp_type;
+
+  $section_manager->append_conditional ($conditional);
+
+  my $variable = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::CUSTOM_CTOR_CAST;
+
+  $conditional = Common::Output::Shared::generate_conditional $wrap_parser;
+  $code_string = nl ('  explicit ' . $cpp_type . '(const ' . $c_type . '* gobject); // always takes a copy');
+  $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+  $section_manager->append_conditional ($conditional);
+  $section_manager->set_variable_for_conditional ($variable, $conditional);
+
+  my $copy_proto = 'no';
+  my $reinterpret = 0;
+  my $definitions = 1;
+
+  $code_string = nl (Common::Output::Shared::gobj_protos_str $c_type, $copy_proto, $reinterpret, $definitions) .
+                 nl () .
+                 nl ('protected:') .
+                 nl ('  ' . $c_type . ' gobject_;') .
+                 nl () .
+                 nl ('private:');
+  $section_manager->append_string ($code_string, $main_section);
+  $section_manager->pop_entry;
+}
+
+sub _output_h_after_namespace ($$$)
+{
+  my ($wrap_parser, $c_type, $cpp_type) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $code_string = nl ('namespace Glib') .
+                    nl ('{');
+  my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::H_AFTER_FIRST_NAMESPACE;
+
+  $section_manager->push_section ($section);
+  $section_manager->append_string ($code_string);
+
+  my $result_type = 'ref';
+  my $take_copy_by_default = 'N/A';
+  my $open_glib_namespace = 0;
+  my $const_function = 0;
+  my $conditional = Common::Output::Shared::wrap_proto $wrap_parser, $c_type, $result_type, $take_copy_by_default, $open_glib_namespace, $const_function;
+  $section_manager->append_conditional ($conditional);
+  $const_function = 1;
+  $conditional = Common::Output::Shared::wrap_proto $wrap_parser, $c_type, $result_type, $take_copy_by_default, $open_glib_namespace, $const_function;
+  $section_manager->append_conditional ($conditional);
+
+  my $full_cpp_type = Common::Output::Shared::get_full_cpp_type ($wrap_parser);
+
+  $code_string = nl () .
+                 nl (Common::Output::Shared::doxy_skip_begin) .
+                 nl ('template <>') .
+                 nl ('class Value< ' . $full_cpp_type . ' > : public Glib::Value_Boxed< ' . $full_cpp_type . ' >') .
+                 nl ('{};') .
+                 nl (Common::Output::Shared::doxy_skip_end) .
+                 nl () .
+                 nl ('} // namespace Glib') .
+                 nl ();
+  $section_manager->append_string ($code_string);
+  $section_manager->pop_entry;
+}
+
+sub _output_cc ($$$$)
+{
+  my ($wrap_parser, $c_type, $cpp_type, $get_type_func) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $variable = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::NO_WRAP_FUNCTION;
+  my $complete_cpp_type = Common::Output::Shared::get_complete_cpp_type $wrap_parser;
+  my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+  my $code_string = nl ('namespace Glib') .
+                    nl ('{') .
+                    nl () .
+                    nl ($complete_cpp_type . '& wrap(' . $c_type . '* object)') .
+                    nl ('{') .
+                    nl ('  return *reinterpret_cast< ' . $complete_cpp_type . '* >(object);') .
+                    nl ('}') .
+                    nl () .
+                    nl ('} // namespace Glib') .
+                    nl ();
+  my $conditional = Common::Output::Shared::generate_conditional $wrap_parser;
+  my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_END;
+
+  $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+  $section_manager->push_section ($section);
+  $section_manager->append_conditional ($conditional);
+  $section_manager->set_variable_for_conditional ($variable, $conditional);
+  $code_string = nl (Common::Output::Shared::open_namespaces $wrap_parser) .
+                 nl ('// static') .
+                 nl ('GType ' . $full_cpp_type . '::get_type()') .
+                 nl ('{') .
+                 nl ('  return ' . $get_type_func . '();') .
+                 nl ('}') .
+                 nl ();
+  $section_manager->append_string ($code_string);
+  $variable = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::CUSTOM_DEFAULT_CTOR;
+  $conditional = Common::Output::Shared::generate_conditional $wrap_parser;
+  $code_string = nl ($full_cpp_type . '::' . $cpp_type . '()') .
+                 nl ('{') .
+                 nl ('  GLIBMM_INITIALIZE_STRUCT(gobject_, ' . $c_type . ');') .
+                 nl ('}') .
+                 nl ();
+  $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+  $section_manager->append_conditional ($conditional);
+  $section_manager->set_variable_for_conditional ($variable, $conditional);
+  $variable = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::CUSTOM_CTOR_CAST;
+  $conditional = Common::Output::Shared::generate_conditional $wrap_parser;
+  $code_string = nl ($full_cpp_type . '::' . $cpp_type . '(const ' . $c_type . '* gobject)') .
+                 nl ('{') .
+                 nl ('  if (gobject)') .
+                 nl ('  {') .
+                 nl ('    gobject_ = *gobject;') .
+                 nl ('  }') .
+                 nl ('  else') .
+                 nl ('  {') .
+                 nl ('    GLIBMM_INITIALIZE_STRUCT(gobject_, ' . $c_type . ');') .
+                 nl ('  }') .
+                 nl ('}') .
+                 nl ();
+  $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+  $section_manager->append_conditional ($conditional);
+  $section_manager->set_variable_for_conditional ($variable, $conditional);
+  $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_NAMESPACE;
+  $section_manager->append_section ($section);
+  $code_string = nl () .
+                 nl (Common::Output::Shared::close_namespaces $wrap_parser);
+  $section_manager->append_string ($code_string);
+  $section_manager->pop_entry;
+}
+
+sub output ($$$$)
+{
+  my ($wrap_parser, $c_type, $cpp_type, $get_type_func) = @_;
+
+  _output_h_in_class $wrap_parser, $c_type, $cpp_type;
+  _output_h_after_namespace $wrap_parser, $c_type, $cpp_type;
+  _output_cc $wrap_parser, $c_type, $cpp_type, $get_type_func;
+}
+
+1; # indicate proper module load.
diff --git a/tools/pm/Common/Output/Ctor.pm b/tools/pm/Common/Output/Ctor.pm
new file mode 100644
index 0000000..86e3fb6
--- /dev/null
+++ b/tools/pm/Common/Output/Ctor.pm
@@ -0,0 +1,145 @@
+# -*- mode: perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# gmmproc - Common::Output::Ctor module
+#
+# Copyright 2012 glibmm development team
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+#
+
+package Common::Output::Ctor;
+
+use strict;
+use warnings;
+
+sub nl
+{
+  return Common::Output::Shared::nl @_;
+}
+
+# TODO: This should be moved to Shared. Here should be a function usable from WrapParser.
+sub initially_unowned_sink ($)
+{
+  my ($wrap_parser) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $conditional = Common::Output::Shared::generate_conditional $wrap_parser;
+  my $variable = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::DERIVES_INITIALLY_UNOWNED;
+  my $code_string = (nl '  if (gobject && g_object_is_floating(gobject_))') .
+                    (nl '  {') .
+                    (nl '    g_object_ref_sink(gobject_); // Stops it from being floating.') .
+                    (nl '  }');
+  $section_manager->append_string_to_conditional ($code_string, $conditional, 1);
+  $section_manager->set_variable_for_conditional ($variable, $conditional);
+
+  return $conditional;
+}
+
+sub ctor_default ($)
+{
+  my ($wrap_parser) = @_;
+  my $cpp_type = Common::Output::Shared::get_cpp_type $wrap_parser;
+
+  unless (defined $cpp_type)
+  {
+# TODO: warn.
+    return;
+  }
+
+  my $code_string = nl $cpp_type, '();';
+  my $main_section = $wrap_parser->get_main_section;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+  my $cpp_class_type = Common::Output::Shared::get_cpp_class_type $wrap_parser;
+  my $base_member = (lc $cpp_class_type) . '_';
+  my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_NAMESPACE;
+  my $conditional = initially_unowned_sink $wrap_parser;
+
+  $section_manager->append_string_to_section ($code_string, $main_section);
+  $code_string = (nl $full_cpp_type, '::', $cpp_type, '()') .
+                 (nl ':') .
+                 (nl '  // Mark this class as non-derived to allow C++ vfuncs to be skipped.') .
+                 (nl '  Glib::ObjectBase(0),') .
+                 (nl '  CppParentType(Glib::ConstructParams(', $base_member, '.init()))') .
+                 (nl '{');
+# TODO: There is SECTION_CC_INITIALIZE_CLASS_EXTRA imported. Check if it is needed.
+  $section_manager->push_section ($section);
+  $section_manager->append_string ($code_string);
+  $section_manager->append_conditional ($conditional);
+  $code_string = (nl '}') .
+                 (nl);
+  $section_manager->append_string ($code_string);
+  $section_manager->pop_entry;
+}
+
+sub wrap_ctor ($$$$)
+{
+  my ($wrap_parser, $c_param_types, $c_param_transfers, $c_prop_names, $cpp_param_types, $cpp_param_names) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $main_section = $wrap_parser->get_main_section;
+  my $cpp_type = Common::Output::Shared::get_cpp_type $wrap_parser;
+  my $cpp_params_str = Common::Output::Shared::paramzipstr $cpp_param_types, $cpp_param_names;
+  my $code_string = (nl 'explicit ', $cpp_type, '(', $cpp_param_str, ');') .
+                    (nl);
+  my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_NAMESPACE;
+  my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+  my $cpp_class_type = Common::Output::Shared::get_cpp_class_type $wrap_parser;
+  my $base_member = (lc $cpp_class_type) . '_';
+  my $conditional = initially_unowned_sink $wrap_parser;
+  my $conversions_store = $wrap_parser->get_conversions_store;
+  my $ctor_params_str = '';
+
+  if (@{$cpp_param_types} > 0)
+  {
+    $ctor_params_str = join ', ', '', (map { join, '', '"', $c_prop_names->[$_], '"', $conversions_store->get_conversion ($cpp_param_types->[$_], $c_param_types->[$_], $c_param_transfers->[$_], $cpp_param_names->[$_]) } 0 .. @{$cpp_param_types}), 'static_cast<char*>(0)';
+  }
+
+  $section_manager->append_string_to_section ($code_string, $main_section);
+  $code_string = (nl $full_cpp_type, '::', $cpp_type, '(', $cpp_params_str, ')') .
+                 (nl ':') .
+                 (nl '  // Mark this class as non-derived to allow C++ vfuncs to be skipped.') .
+                 (nl '  Glib::ObjectBase(0),') .
+                 (nl '  CppParentType(Glib::ConstructParams(', $base_member, '.init()', $ctor_params_str, '))') .
+                 (nl '{');
+# TODO: There is SECTION_CC_INITIALIZE_CLASS_EXTRA imported. Check if it is needed.
+  $section_manager->push_section ($section);
+  $section_manager->append_string ($code_string);
+  $section_manager->append_conditional ($conditional);
+  $code_string = (nl '}') .
+                 (nl);
+  $section_manager->append_string ($code_string);
+  $section_manager->pop_entry;
+}
+
+sub wrap_create ($$$)
+{
+  my ($wrap_parser, $cpp_param_types, $cpp_param_names) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $main_section = $wrap_parser->get_main_section;
+  my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_NAMESPACE;
+  my $cpp_type = Common::Output::Shared::get_cpp_type $wrap_parser;
+  my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+  my $cpp_params_str = Common::Output::Shared::paramzipstr $cpp_param_types, $cpp_param_names;
+  my $cpp_names_str = join ', ', @{$cpp_param_names};
+  my $code_string = (nl 'static Glib::RefPtr< ', $cpp_type, ' > create(', $cpp_params_str, ')');
+
+  $section_manager->append_string_to_section ($code_string, $main_section);
+  $code_string = (nl 'Glib::RefPtr< ', $full_cpp_type, ' > ', $full_cpp_type, '::create(', $cpp_params_str, ')') .
+                 (nl '{') .
+                 (nl '  return Glib::RefPtr< ', $cpp_type, ' >(new ', $cpp_type, '(', $cpp_names_str, '));') .
+                 (nl '}') .
+                 (nl);
+  $section_manager->append_string_to_section ($code_string, $section);
+}
+
+1; # indicate proper module load.
diff --git a/tools/pm/Common/Output/Enum.pm b/tools/pm/Common/Output/Enum.pm
new file mode 100644
index 0000000..527a2c5
--- /dev/null
+++ b/tools/pm/Common/Output/Enum.pm
@@ -0,0 +1,124 @@
+# -*- mode: perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# gmmproc - Common::Output::Enum module
+#
+# Copyright 2012 glibmm development team
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+#
+
+package Common::Output::Enum;
+
+use strict;
+use warnings;
+
+sub nl
+{
+  return Common::Output::Shared::nl @_;
+}
+
+sub _output_enum ($$$)
+{
+  my ($wrap_parser, $cpp_type, $members) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $main_section = $wrap_parser->get_main_section;
+  my $string_members = Common::Output::Shared::convert_members_to_strings $members;
+  my $code_string = nl ('enum ' . $cpp_type) .
+                    nl ('{') .
+                    nl (join ((nl ','), @{$string_members})) .
+                    nl ('};') .
+                    nl ();
+
+  $section_manager->append_string_to_section ($code_string, $main_section);
+}
+
+sub _output_flag_ops ($$$)
+{
+  my ($wrap_parser, $cpp_type, $flags) = @_;
+
+  if ($flags)
+  {
+    my $section_manager = $wrap_parser->get_section_manager;
+    my $container_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+    my $full_cpp_type = join '::', $container_cpp_type, $cpp_type;
+    my $code_string .= nl ('inline ' . $full_cpp_type . ' operator|(' . $full_cpp_type . ' lhs, ' . $full_cpp_type . ' rhs)') .
+                       nl ('  { return static_cast<' . $full_cpp_type . '>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs)); }') .
+                       nl () .
+                       nl ('inline ' . $full_cpp_type . ' operator&(' . $full_cpp_type . ' lhs, ' . $full_cpp_type . ' rhs)') .
+                       nl ('  { return static_cast<' . $full_cpp_type . '>(static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs)); }') .
+                       nl () .
+                       nl ('inline ' . $full_cpp_type . ' operator^(' . $full_cpp_type . ' lhs, ' . $full_cpp_type . ' rhs)') .
+                       nl ('{ return static_cast<' . $full_cpp_type . '>(static_cast<unsigned>(lhs) ^ static_cast<unsigned>(rhs)); }') .
+                       nl () .
+                       nl ('inline ' . $full_cpp_type . ' operator~(' . $full_cpp_type . ' flags)') .
+                       nl ('  { return static_cast<' . $full_cpp_type . '>(~static_cast<unsigned>(flags)); }') .
+                       nl () .
+                       nl ('inline ' . $full_cpp_type . '& operator|=(' . $full_cpp_type . '& lhs, ' . $full_cpp_type . ' rhs)') .
+                       nl ('  { return (lhs = static_cast<' . $full_cpp_type . '>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs))); }') .
+                       nl () .
+                       nl ('inline ' . $full_cpp_type . '& operator&=(' . $full_cpp_type . '& lhs, ' . $full_cpp_type . ' rhs)') .
+                       nl ('  { return (lhs = static_cast<' . $full_cpp_type . '>(static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs))); }') .
+                       nl () .
+                       nl ('inline ' . $full_cpp_type . '& operator^=(' . $full_cpp_type . '& lhs, ' . $full_cpp_type . ' rhs)') .
+                       nl ('  { return (lhs = static_cast<' . $full_cpp_type . '>(static_cast<unsigned>(lhs) ^ static_cast<unsigned>(rhs))); }') .
+                       nl ();
+
+    if ($container_cpp_type)
+    {
+      my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::H_AFTER_FIRST_CLASS;
+
+      $section_manager->append_string_to_section ($code_string, $section);
+    }
+    else
+    {
+      $section_manager->append_string_to_section ($code_string, $wrap_parser->get_main_section);
+    }
+  }
+}
+
+sub _output_gtype_func_h ($$$$)
+{
+  my ($wrap_parser, $cpp_type, $flags, $get_type_func) = @_;
+  my $type = undef;
+
+  if ($flags)
+  {
+    $type = Common::Output::Shared::FLAGS_TYPE;
+  }
+  else
+  {
+    $type = Common::Output::Shared::ENUM_TYPE;
+  }
+
+  Common::Output::Shared::output_enum_gtype_func_h $wrap_parser, $cpp_type, $type, $get_type_func;
+}
+
+sub _output_gtype_func_cc ($$$)
+{
+  my ($wrap_parser, $cpp_type, $get_type_func) = @_;
+
+  Common::Output::Shared::output_enum_gtype_func_cc $wrap_parser, $cpp_type, $get_type_func;
+}
+
+sub output ($$$$$)
+{
+  my ($wrap_parser, $cpp_type, $members, $flags, $get_type_func) = @_;
+
+  _output_enum $wrap_parser, $cpp_type, $members;
+  _output_flag_ops $wrap_parser, $cpp_type, $flags;
+  _output_gtype_func_h $wrap_parser, $cpp_type, $flags, $get_type_func;
+  _output_gtype_func_cc $wrap_parser, $cpp_type, $get_type_func;
+}
+
+1; # indicate proper module load.
diff --git a/tools/pm/Common/Output/GError.pm b/tools/pm/Common/Output/GError.pm
new file mode 100644
index 0000000..3dfba0d
--- /dev/null
+++ b/tools/pm/Common/Output/GError.pm
@@ -0,0 +1,127 @@
+# -*- mode: perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# gmmproc - Common::Output::GError module
+#
+# Copyright 2012 glibmm development team
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+#
+
+package Common::Output::GError;
+
+use strict;
+use warnings;
+
+sub nl
+{
+  return Common::Output::Shared::nl @_;
+}
+
+sub _output_gerror ($$$)
+{
+  my ($wrap_parser, $cpp_type, $members) = @_;
+  my $string_members = Common::Output::Shared::convert_members_to_strings ($members);
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $namespaces = $wrap_parser->get_namespaces;
+  my $wrap_init = 'wrap_init()';
+
+  if (@{$namespaces})
+  {
+    $wrap_init = '::' . $namespaces->[0] . '::' . $wrap_init;
+  }
+
+  my $code_string = nl ('class ' . $cpp_type . ' : public Glib::Error') .
+                    nl ('{') .
+                    nl ('public:') .
+                    nl ('  enum Code') .
+                    nl ('  {') .
+                    nl (join nl (','), @{$string_members}) .
+                    nl ('  };') .
+                    nl () .
+                    nl ('  ' . $cpp_type . '(Code error_code, const Glib::ustring& error_message);') .
+                    nl ('  explicit ' . $cpp_type . '(GError* gobject);') .
+                    nl ('  Code code() const;') .
+                    nl () .
+                    nl (Common::Output::Shared::doxy_skip_begin) .
+                    nl ('private:') .
+                    nl () .
+                    nl ('  static void throw_func(GError* gobject);') .
+                    nl () .
+                    nl ('  friend void ' . $wrap_init . '; // uses throw_func()') .
+                    nl (Common::Output::Shared::doxy_skip_end) .
+                    nl ('};') .
+                    nl ();
+
+  $section_manager->append_string_to_section ($code_string, $wrap_parser->get_main_section);
+}
+
+sub _output_gerror_gtype_h ($$$)
+{
+  my ($wrap_parser, $cpp_type, $get_type_func) = @_;
+
+  Common::Output::Shared::output_enum_gtype_func_h $wrap_parser, $cpp_type, Common::Output::Shared::ENUM_TYPE, $get_type_func;
+}
+
+sub _output_gerror_impl ($$$)
+{
+  my ($wrap_parser, $cpp_type, $domain) = @_;
+  my $container_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+  my $full_cpp_type = join '::', $container_cpp_type, $cpp_type;
+  my $section_manager->get_section_manager;
+  my $code_string = nl (Common::Output::Shared::open_namespaces $wrap_parser) .
+                    nl ($full_cpp_type . '::' . $cpp_type . '(' . $full_cpp_type . '::Code error_code, const Glib::ustring& error_message)') .
+                    nl (':') .
+                    nl ('  Glib::Error(g_quark_from_static_string ("' . $domain . '"), error_code, error_message)') .
+                    nl ('{}') .
+                    nl () .
+                    nl ($full_cpp_type . '::' . $cpp_type . '(GError* gobject)') .
+                    nl (':') .
+                    nl ('  Glib::Error(gobject)') .
+                    nl ('{}') .
+                    nl () .
+                    nl ($full_cpp_type . '::Code ' . $full_cpp_type . '::code() const') .
+                    nl ('{') .
+                    nl ('  return static_cast<Code>(Glib::Error::code());') .
+                    nl ('}') .
+                    nl () .
+                    nl ('// static') .
+                    nl ('void ' . $full_cpp_type . '::throw_func(GError* gobject)') .
+                    nl ('{') .
+                    nl ('  throw ' . $full_cpp_type . '(gobject);') .
+                    nl ('}') .
+                    nl () .
+                    Common::Output::Shared::close_namespaces $wrap_parser;
+  my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_END;
+
+  $section_manager->append_string_to_section ($code_string, $section);
+}
+
+sub _output_gerror_gtype_cc ($$$)
+{
+  my ($wrap_parser, $cpp_type, $get_type_func) = @_;
+
+  Common::Output::Shared::output_enum_gtype_func_cc ($wrap_parser, $cpp_type, $get_type_func);
+}
+
+sub output ($$$$$)
+{
+  my ($wrap_parser, $cpp_type, $members, $domain, $get_type_func) = @_;
+
+  _output_gerror $wrap_parser, $cpp_type, $members;
+  _output_gerror_gtype_h $wrap_parser, $cpp_type, $get_type_func;
+  _output_gerror_impl $wrap_parser, $cpp_type, $domain;
+  _output_gerror_gtype_cc $wrap_parser, $cpp_type, $get_type_func;
+}
+
+1; # indicate proper module load.
diff --git a/tools/pm/Common/Output/GObject.pm b/tools/pm/Common/Output/GObject.pm
new file mode 100644
index 0000000..c76f5b8
--- /dev/null
+++ b/tools/pm/Common/Output/GObject.pm
@@ -0,0 +1,502 @@
+# -*- mode: perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# gmmproc - Common::Output::GObject module
+#
+# Copyright 2011, 2012 glibmm development team
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+#
+
+package Common::Output::GObject;
+
+use strict;
+use warnings;
+
+sub nl
+{
+  return Common::Output::Shared::nl @_;
+}
+
+sub _output_h_before_namespace ($$$)
+{
+  my ($wrap_parser, $c_type, $c_class_type) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $cpp_class_type = Common::Output::Shared::get_cpp_class_type $wrap_parser;
+  my $subconditional = Common::Output::Shared::struct_prototype $wrap_parser, $c_type, $c_class_type;
+  my $variable = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::NO_WRAP_FUNCTION;
+  my $conditional = Common::Output::Shared::generate_conditional ($wrap_parser);
+  my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::H_BEFORE_FIRST_NAMESPACE;
+
+  $section_manager->append_conditional_to_conditional ($subconditional, $conditional, 0);
+  $section_manager->push_section ($section);
+  $section_manager->append_conditional ($conditional);
+  $section_manager->set_variable_for_conditional ($variable, $conditional);
+  my $code_string = Common::Output::Shared::open_namespaces ($wrap_parser) .
+                    nl ('class ' . $cpp_class_type . ';') .
+                    Common::Output::Shared::close_namespaces ($wrap_parser) .
+                    nl ();
+  $section_manager->append_string ($code_string);
+  $section_manager->pop_entry;
+}
+
+sub _output_h_in_class ($$$$$$)
+{
+  my ($wrap_parser, $c_type, $c_parent_type, $c_class_type, $cpp_type, $cpp_parent_type) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $main_section = $wrap_parser->get_main_section;
+  my $cpp_class_type = Common::Output::Shared::get_cpp_class_type $wrap_parser;
+  my $code_string = nl (Common::Output::Shared::doxy_skip_begin) .
+                    nl () .
+                    nl ('public:') .
+                    nl ('  typedef ' . $cpp_type . ' CppObjectType;') .
+                    nl ('  typedef ' . $cpp_class_type . ' CppClassType;') .
+                    nl ('  typedef ' . $cpp_parent_type . ' CppParentType;') .
+                    nl ('  typedef ' . $c_type . ' BaseObjectType;') .
+                    nl ('  typedef ' . $c_class_type . ' BaseClassType;') .
+                    nl ('  typedef ' . $c_parent_type . ' BaseParentType;') .
+                    nl ();
+
+  $section_manager->push_section ($main_section);
+  $section_manager->append_string ($code_string);
+
+  my $variable = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::PROTECTED_GCLASS;
+  my $conditional = Common::Output::Shared::generate_conditional ($wrap_parser);
+
+  $code_string = nl ('protected:');
+  $section_manager->append_string_to_conditional ($code_string, $conditional, 1);
+  $code_string = nl ('private:');
+  $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+  $section_manager->append_conditional ($conditional);
+  $section_manager->set_variable_for_conditional ($variable, $conditional);
+
+  my $virtual_dtor = 1;
+  my $base_member = lc ($cpp_class_type) . '_';
+
+  $code_string = nl ('  friend class ' . $cpp_class_type . ';') .
+                 nl ('  static CppClassType ' . $base_member . '_;') .
+                 nl () .
+                 nl ('private:') .
+                 nl ('  // noncopyable') .
+                 nl (Common::Output::Shared::copy_protos_str $cpp_type) .
+                 nl () .
+                 nl ('protected:') .
+                 nl ('  explicit ' . $cpp_type . '(const Glib::ConstructParams& construct_params);') .
+                 nl ('  explicit ' . $cpp_type . '(' . $c_type . '* castitem);') .
+                 nl () .
+                 nl (Common::Output::Shared::doxy_skip_end) .
+                 nl () .
+                 nl ('public:') .
+                 nl (Common::Output::Shared::dtor_proto_str $cpp_type, $virtual_dtor) .
+                 nl () .
+                 nl (Common::Output::Shared::doxy_skip_begin) .
+                 nl ('  static GType get_type() G_GNUC_CONST;');
+  $section_manager->append_string ($code_string);
+  $code_string = nl ('  static GType get_type(GTypeModule* module) G_GNUC_CONST');
+  $variable = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::DYNAMIC_GTYPE_REGISTRATION;
+  $conditional = Common::Output::Shared::generate_conditional ($wrap_parser);
+  $section_manager->append_string_to_conditional ($code_string, $conditional, 1);
+  $section_manager->append_conditional ($conditional);
+  $section_manager->set_variable_for_conditional ($variable, $conditional);
+
+  my $copy_proto = 'no';
+  my $reinterpret = 1;
+  my $definitions = 1;
+
+  $code_string = nl ('  static GType get_base_type() G_GNUC_CONST;') .
+                 nl (Common::Output::Shared::doxy_skip_end) .
+                 nl () .
+                 nl (Common::Output::Shared::gobj_protos_str $c_type, $copy_proto, $reinterpret, $definitions) .
+                 nl () .
+                 nl ('private:');
+  $section_manager->append_string ($code_string);
+  $section_manager->pop_entry;
+}
+
+sub _output_h_after_namespace ($$)
+{
+  my ($wrap_parser, $c_type) = @_;
+  my $result_type = 'refptr';
+  my $take_copy_by_default = 'no';
+  my $open_glib_namespace = 1;
+  my $const_function = 0;
+  my $conditional = Common::Output::Shared::wrap_proto $wrap_parser, $c_type, $result_type, $take_copy_by_default, $open_glib_namespace, $const_function;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::H_AFTER_FIRST_NAMESPACE;
+
+  $section_manager->append_conditional_to_section ($conditional, $section);
+}
+
+sub _output_p_h ($$$$$)
+{
+  my ($wrap_parser, $c_type, $c_class_type, $c_parent_class_type, $cpp_parent_type) = @_;
+  my $cpp_class_type = Common::Output::Shared::get_cpp_class_type $wrap_parser;
+  my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+  my $cpp_parent_class_type = $cpp_parent_type . '::CppClassType';
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $code_string = nl ('#include <glibmm/class.h>') .
+                    nl () .
+                    Common::Output::Shared::open_namespaces ($wrap_parser) .
+                    nl () .
+                    nl ('class ' . $cpp_class_type . ' : public Glib::Class') .
+                    nl ('{') .
+                    nl ('public:') .
+                    nl (Common::Output::Shared::doxy_skip_begin) .
+                    nl ('  typedef ' . $full_cpp_type . ' CppObjectType;') .
+                    nl ('  typedef ' . $c_type . ' BaseObjectType;');
+  my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_H_CONTENTS;
+
+  $section_manager->push_section ($section);
+  $section_manager->append_string ($code_string);
+
+  my $do_not_derive_gtype_var = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::DO_NOT_DERIVE_GTYPE;
+  my $conditional = Common::Output::Shared::generate_conditional ($wrap_parser);
+
+  $code_string = nl ('  typedef ' . $cpp_parent_class_type . ' CppClassParent;');
+  $section_manager->append_string_to_conditional ($code_string, $conditional, 1);
+  $code_string = nl ('  typedef ' . $c_class_type . ' BaseClassType;') .
+                 nl ('  typedef ' . $cpp_parent_class_type . ' CppClassParent;') .
+                 nl ('  typedef ' . $c_parent_class_type . ' BaseClassParent;');
+  $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+  $section_manager->append_conditional ($conditional);
+  $section_manager->set_variable_for_conditional ($do_not_derive_gtype_var, $conditional);
+  $code_string = nl () .
+                 nl ('  friend class ' . $full_cpp_type . ';') .
+                 nl (Common::Output::Shared::doxy_skip_end) .
+                 nl () .
+                 nl ('  const Glib::Class& init();') .
+                 nl ();
+  $section_manager->append_string ($code_string);
+  $conditional = Common::Output::Shared::generate_conditional ($wrap_parser);
+
+  my $dynamic_gtype_registration_var = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::DYNAMIC_GTYPE_REGISTRATION;
+
+  $code_string = nl ('  const Glib::Class& init(GTypeModule* module);');
+  $section_manager->append_string_to_conditional ($code_string, $conditional, 1);
+  $section_manager->append_conditional ($conditional);
+  $section_manager->set_variable_for_conditional ($dynamic_gtype_registration_var, $conditional);
+  $conditional = Common::Output::Shared::generate_conditional ($wrap_parser);
+  $code_string = nl ('  static void class_init_function(void* g_class, void* class_data);');
+  $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+  $section_manager->append_conditional ($conditional);
+  $section_manager->set_variable_for_conditional ($do_not_derive_gtype_var, $conditional);
+  $code_string = nl ('  static Glib::ObjectBase* wrap_new(GObject*);') .
+                 nl () .
+                 nl ('protected:');
+  $section_manager->append_string ($code_string);
+
+  my @h_sections =
+  (
+    (Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_H_DEFAULT_SIGNAL_HANDLERS),
+    (Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_H_VFUNCS)
+  );
+
+  foreach my $h_section (@h_sections)
+  {
+    $section_manager->append_section ($h_section);
+    $section_manager->append_string (nl);
+  }
+
+  $code_string = nl ('};') .
+                 nl () .
+                 Common::Output::Shared::close_namespaces ($wrap_parser);
+  $section_manager->append_string ($code_string);
+  $section_manager->pop_entry;
+}
+
+sub _output_cc ($$$$$$)
+{
+  my ($wrap_parser, $c_type, $c_parent_type, $get_type_func, $cpp_type, $cpp_parent_type) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $complete_cpp_type = Common::Output::Shared::get_complete_cpp_type $wrap_parser;
+  my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+  my $code_string = nl ('namespace Glib') .
+                    nl ('{') .
+                    nl () .
+                    nl ('Glib::RefPtr< ' . $complete_cpp_type . ' > wrap(' . $c_type . '* object, bool take_copy)') .
+                    nl ('{') .
+                    nl ('  return Glib::RefPtr< ' . $complete_cpp_type . ' >(dynamic_cast< ' . $complete_cpp_type . ' >(Glib::wrap_auto (static_cast< GObject* >(object), take_copy)));') .
+                    nl ('  // We use dynamic_cast<> in case of multiple inheritance.') .
+                    nl ('}') .
+                    nl () .
+                    nl ('} // namespace Glib') .
+                    nl ();
+  my $no_wrap_function_var = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::NO_WRAP_FUNCTION;
+  my $conditional = Common::Output::Shared::generate_conditional ($wrap_parser);
+  my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_END;
+
+  $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+  $section_manager->push_section ($section);
+  $section_manager->append_conditional ($conditional);
+  $section_manager->set_variable_for_conditional ($no_wrap_function_var, $conditional);
+  $code_string = Common::Output::Shared::open_namespaces ($wrap_parser) .
+                 nl ($c_type . '* ' . $full_cpp_type . '::gobj_copy()') .
+                 nl ('{') .
+                 nl ('  reference();') .
+                 nl ('  return gobj();') .
+                 nl ('}') .
+                 nl ();
+  $section_manager->append_string ($code_string);
+  $conditional = Common::Output::Shared::generate_conditional ($wrap_parser);
+
+  my $custom_ctor_cast_var = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::CUSTOM_CTOR_CAST;
+
+  $code_string = nl ($full_cpp_type . '::' . $cpp_type . '(const Glib::ConstructParams& construct_params)') .
+                 nl (':') .
+                 nl ('  ' . $cpp_parent_type . '(construct_params)') .
+                 nl ('{');
+  $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+
+  my $subconditional = Common::Output::Ctor::initially_unowned_sink $wrap_parser;
+
+  $section_manager->append_conditional_to_conditional ($subconditional, $conditional, 0);
+  $code_string = nl ('}') .
+                 nl () .
+                 nl ($full_cpp_type . '::' . $cpp_type . '(' . $c_type . '* castitem)') .
+                 nl (':') .
+                 nl ('  ' . $cpp_parent_type . '(static_cast< ' . $c_parent_type . '* >(castitem))') .
+                 nl ('{}') .
+                 nl ();
+  $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+  $section_manager->append_conditional ($conditional);
+  $section_manager->set_variable_for_conditional ($custom_ctor_cast_var, $conditional);
+  $conditional = Common::Output::Shared::generate_conditional ($wrap_parser);
+
+  my $custom_dtor_var = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::CUSTOM_DTOR;
+  my $cpp_class_type = Common::Output::Shared::get_cpp_class_type $wrap_parser;
+
+  $code_string = nl ($full_cpp_type . '::~' . $cpp_type . '()') .
+                 nl ('{}') .
+                 nl ();
+  $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+  $section_manager->append_conditional ($conditional);
+  $section_manager->set_variable_for_conditional ($custom_dtor_var, $conditional);
+
+  my $base_member = lc ($cpp_class_type) . '_';
+
+# TODO: move to Shared?
+  $code_string = nl ($full_cpp_type . '::CppClassType ' . $full_cpp_type . '::' . $base_member . '; // Initialize static member') .
+                 nl () .
+                 nl ('GType ' . $full_cpp_type . '::get_type()') .
+                 nl ('{') .
+                 nl ('  return ' . $base_member . '_.init().get_type();') .
+                 nl ('}') .
+                 nl ();
+  $section_manager->append_string ($code_string);
+  $conditional = Common::Output::Shared::generate_conditional ($wrap_parser);
+  $code_string = nl ('GType ' . $full_cpp_type . '::get_type(GTypeModule* module)') .
+                 nl ('{') .
+                 nl ('  return ' . $base_member . '_.init(module).get_type();') .
+                 nl ('}') .
+                 nl ();
+
+  my $dynamic_gtype_registration_var = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::DYNAMIC_GTYPE_REGISTRATION;
+
+  $section_manager->append_string_to_conditional ($code_string, $conditional, 1);
+  $section_manager->append_conditional ($conditional);
+  $section_manager->set_variable_for_conditional ($dynamic_gtype_registration_var, $conditional);
+  $code_string = nl ('GType ' . $full_cpp_type . '::get_base_type()') .
+                 nl ('{') .
+                 nl ('  return ' . $get_type_func . '();') .
+                 nl ('}') .
+                 nl ();
+  $section_manager->append_string ($code_string);
+
+  my @sections =
+  (
+    (Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_NAMESPACE),
+    (Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_SIGNAL_PROXIES),
+    (Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_PROPERTY_PROXIES),
+    (Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_DEFAULT_SIGNAL_HANDLERS),
+    (Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_VFUNCS),
+    (Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_VFUNCS_CPP_WRAPPER),
+    (Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_CC_NAMESPACE)
+  );
+
+  foreach my $cc_section (@sections)
+  {
+    $section_manager->append_section ($cc_section);
+    $section_manager->append_string (nl);
+  }
+
+  $section_manager->append_string (Common::Output::Shared::close_namespaces ($wrap_parser));
+}
+
+sub _output_p_cc ($$$$)
+{
+  my ($wrap_parser, $c_type, $c_type_class, $get_type_func) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+  my $full_cpp_class_type = Common::Output::Shared::get_full_cpp_class_type $wrap_parser;
+  my $code_string = nl ('const Glib::Class& ' . $full_cpp_class_type . '::init()') .
+                    nl ('{') .
+                    nl ('  if (!gtype_) // create the GType if necessary') .
+                    nl ('  {');
+  my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_CC_NAMESPACE;
+
+  $section_manager->push_section ($section);
+  $section_manager->append_string ($code_string);
+
+  my $conditional = Common::Output::Shared::generate_conditional ($wrap_parser);
+  my $do_not_derive_gtype_var = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::DO_NOT_DERIVE_GTYPE;
+
+  $code_string = nl ('    gtype_ = CppClassParent::CppObjectType::get_type();');
+  $section_manager->append_string_to_conditional ($code_string, $conditional, 1);
+  $code_string = nl ('    // Glib::Class has to know the class init function to clone custom types.') .
+                 nl ('    class_init_func_ = &' . $full_cpp_class_type . '::class_init_function;') .
+                 nl () .
+                 nl ('    // This is actually just optimized away, apparently with no harm.') .
+                 nl ('    // Make sure that the parent type has been created.') .
+                 nl ('    //CppClassParent::CppObjectType::get_type();') .
+                 nl () .
+                 nl ('    // Create the wrapper type, with the same class/instance size as the base type.') .
+                 nl ('    register_derived_type(' . $get_type_func . '());') .
+                 nl () .
+                 nl ('    // Add derived versions of interfaces, if the C type implements any interfaces:');
+  $section_manager->push_conditional ($conditional, 0);
+  $section_manager->append_string ($code_string);
+  $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_CC_IMPLEMENTS_INTERFACES;
+  $section_manager->append_section ($section);
+  $section_manager->append_string (nl);
+  $section_manager->pop_entry;
+  $section_manager->append_conditional ($conditional);
+  $section_manager->set_variable_for_conditional ($do_not_derive_gtype_var, $conditional);
+  $code_string = nl ('  }') .
+                 nl () .
+                 nl ('  return *this;') .
+                 nl ('}') .
+                 nl ();
+  $section_manager->append_string ($code_string);
+  $conditional = Common::Output::Shared::generate_conditional ($wrap_parser);
+
+  my $dynamic_gtype_registration_var = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::DYNAMIC_GTYPE_REGISTRATION;
+
+  $code_string = nl ('const Glib::Class& ' . $full_cpp_class_type . '::init(GTypeModule* module)') .
+                 nl ('{') .
+                 nl ('  if (!gtype_) // create the GType if necessary') .
+                 nl ('  {');
+  $section_manager->push_conditional ($conditional, 1);
+  $section_manager->append_string ($code_string);
+
+  my $subconditional = Common::Output::Shared::generate_conditional ($wrap_parser);
+
+  $code_string = nl ('    // Do not derive a GType, or use a derived klass:') .
+                 nl ('    gtype_ = CppClassParent::CppObjectType::get_type();');
+  $section_manager->append_string_to_conditional ($code_string, $subconditional, 1);
+  $code_string = nl ('    // Glib::Class has to know the class init function to clone custom types.') .
+                 nl ('    class_init_func_ = &' . $full_cpp_class_type . '::class_init_function;') .
+                 nl () .
+                 nl ('    // This is actually just optimized away, apparently with no harm.') .
+                 nl ('    // Make sure that the parent type has been created.') .
+                 nl ('    //CppClassParent::CppObjectType::get_type();') .
+                 nl () .
+                 nl ('    // Create the wrapper type, with the same class/instance size as the base type.') .
+                 nl ('    register_derived_type(' . $get_type_func . '(), module);') .
+                 nl () .
+                 nl ('    // Add derived versions of interfaces, if the C type implements any interfaces:');
+  $section_manager->push_conditional ($subconditional, 1);
+  $section_manager->append_string ($code_string);
+  $section_manager->append_section ($section);
+  $section_manager->append_string (nl);
+  $section_manager->pop_entry; # subconditional, 1
+  $section_manager->append_conditional ($subconditional);
+  $section_manager->set_variable_for_conditional ($do_not_derive_gtype_var, $subconditional);
+  $code_string = nl ('  }') .
+                 nl () .
+                 nl ('  return *this;') .
+                 nl ('}') .
+                 nl ();
+  $section_manager->append_string ($code_string);
+  $section_manager->pop_entry; # conditional, 1
+  $section_manager->append_conditional ($conditional);
+  $section_manager->set_variable_for_conditional ($dynamic_gtype_registration_var, $conditional);
+  $conditional = Common::Output::Shared::generate_conditional ($wrap_parser);
+  $code_string = nl ('void ' . $full_cpp_class_type . '::class_init_function(void* g_class, void* class_data)') .
+                 nl ('{') .
+                 nl ('  BaseClassType* const klass = static_cast< BaseClassType* >(g_class);') .
+                 nl ('  CppClassParent::class_init_function(klass, class_data);') .
+                 nl ();
+  $section_manager->push_conditional ($conditional, 0);
+  $section_manager->append_string ($code_string);
+
+  my @p_cc_sections_inside_func =
+  (
+    (Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_CC_INIT_VFUNCS),
+    (Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_CC_INIT_DEFAULT_SIGNAL_HANDLERS)
+  );
+
+  foreach my $p_cc_section (@p_cc_sections_inside_func)
+  {
+    $section_manager->append_section ($section);
+    $section_manager->append_string (nl);
+  }
+  $code_string = nl ('}') .
+                 nl ();
+  $section_manager->append_string ($code_string);
+  $section_manager->pop_entry; # conditional, 0
+  $section_manager->append_conditional ($conditional);
+  $section_manager->set_variable_for_conditional ($do_not_derive_gtype_var, $conditional);
+
+  my @p_cc_sections_outside_func =
+  (
+    (Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_CC_VFUNCS),
+    (Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_CC_DEFAULT_SIGNAL_HANDLERS)
+  );
+
+  foreach my $p_cc_section (@p_cc_sections_outside_func)
+  {
+    $section_manager->append_section ($section);
+    $section_manager->append_string (nl);
+  }
+
+  $code_string = nl ('Glib::ObjectBase* ' . $full_cpp_class_type . '::wrap_new(GObject* object)') .
+                 nl ('{') .
+                 nl ('  return new ' . $full_cpp_type . '(static_cast< ' . $c_type . '* >(object));') .
+                 nl ('}') .
+                 nl ();
+  $conditional = Common::Output::Shared::generate_conditional ($wrap_parser);
+
+  my $custom_wrap_new_var = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::CUSTOM_WRAP_NEW;
+
+  $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+  $section_manager->append_conditional ($conditional);
+  $section_manager->set_variable_for_conditional ($custom_wrap_new_var, $conditional);
+  $section_manager->append_string (Common::Output::Shared::close_namespaces $wrap_parser);
+  $section_manager->pop_entry;
+}
+
+sub output ($$$$$$$$)
+{
+  my ($wrap_parser, $c_type, $c_class_type, $c_parent_type, $c_parent_class_type, $get_type_func, $cpp_type, $cpp_parent_type) = @_;
+
+  _output_h_before_namespace $wrap_parser, $c_type, $c_class_type;
+  _output_h_in_class $wrap_parser, $c_type, $c_parent_type, $c_class_type, $cpp_type, $cpp_parent_type;
+  _output_h_after_namespace $wrap_parser, $c_type;
+  _output_p_h $wrap_parser, $c_type, $c_class_type, $c_parent_class_type, $cpp_parent_type;
+  _output_cc $wrap_parser, $c_type, $c_parent_type, $get_type_func, $cpp_type, $cpp_parent_type;
+  _output_p_cc $wrap_parser, $c_type, $c_class_type, $get_type_func;
+}
+
+sub implements_interface ($$$)
+{
+  my ($wrap_parser, $interface, $ifdef) = @_;
+  my $section_manager = $wrap_parser->get_section_interface;
+  my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_CC_IMPLEMENTS_INTERFACES;
+  my $code_string = (Common::Output::Shared::ifdef $ifdef) .
+                    (nl '  ', $interface, '::add_interface(get_type());') .
+                    (Common::Output::Shared::endif $ifdef);
+
+  $section_manager->append_string_to_section ($code_string, $section);
+}
+
+1; # indicate proper module load.
diff --git a/tools/pm/Common/Output/Generic.pm b/tools/pm/Common/Output/Generic.pm
new file mode 100644
index 0000000..8ec865f
--- /dev/null
+++ b/tools/pm/Common/Output/Generic.pm
@@ -0,0 +1,55 @@
+# -*- mode: perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# gmmproc - Common::Output::Generic module
+#
+# Copyright 2011 glibmm development team
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+#
+
+package Common::Output::Generic;
+
+use strict;
+use warnings;
+
+sub nl
+{
+  return Common::Output::Shared::nl @_;
+}
+
+sub output ($$$)
+{
+  my ($wrap_parser, $c_type, $cpp_type) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $main_section = $wrap_parser->get_main_section;
+  my $cc_end_section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_END;
+  my $cc_namespace_section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_NAMESPACE;
+  my $code_string = nl ('public:') .
+                    nl (Common::Output::Shared::doxy_skip_begin) .
+                    nl ('  typedef ' . $cpp_type . ' CppObjectType;') .
+                    nl ('  typedef ' . $c_type . ' BaseObjectType;') .
+                    nl (Common::Output::Shared::doxy_skip_end) .
+                    nl () .
+                    nl ('private:') .
+                    nl ();
+
+  $section_manager->append_string_to_section ($code_string, $main_section);
+  $section_manager->push_section ($cc_end_section);
+  $section_manager->append_string (Common::Output::Shared::open_namespaces $wrap_parser);
+  $section_manager->append_section ($cc_namespace_section);
+  $section_manager->append_string (Common::Output::Shared::close_namespaces $wrap_parser);
+  $section_manager->pop_entry;
+}
+
+1; # indicate proper module load.
diff --git a/tools/pm/Common/Output/GtkObject.pm b/tools/pm/Common/Output/GtkObject.pm
new file mode 100644
index 0000000..0b34351
--- /dev/null
+++ b/tools/pm/Common/Output/GtkObject.pm
@@ -0,0 +1,26 @@
+# -*- mode: perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# gmmproc - Common::Output::GtkObject module
+#
+# Copyright 2012 glibmm development team
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+#
+
+package Common::Output::GtkObject;
+
+use strict;
+use warnings;
+
+1; # indicate proper module load.
diff --git a/tools/pm/Common/Output/Interface.pm b/tools/pm/Common/Output/Interface.pm
new file mode 100644
index 0000000..a4b9b15
--- /dev/null
+++ b/tools/pm/Common/Output/Interface.pm
@@ -0,0 +1,378 @@
+# -*- mode: perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# gmmproc - Common::Output::Interface module
+#
+# Copyright 2012 glibmm development team
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+#
+
+package Common::Output::Interface;
+
+use strict;
+use warnings;
+
+sub nl
+{
+  return Common::Output::Shared::nl @_;
+}
+
+sub _output_h_before_first_namespace ($$$)
+{
+  my ($wrap_parser, $c_type, $c_class_type) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $conditional = Common::Output::Shared::struct_prototype $wrap_parser, $c_type, $c_class_type;
+  my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::H_BEFORE_FIRST_NAMESPACE;
+
+  $section_manager->push_section ($section);
+  $section_manager->append_conditional ($conditional);
+
+  my $cpp_class_type = Common::Output::Shared::get_cpp_class_type $wrap_parser;
+  my $code_string = nl (Common::Output::Shared::open_namespaces $wrap_parser) .
+                    nl () .
+                    nl ('class ' . $cpp_class_type . ';') .
+                    nl () .
+                    nl (Common::Output::Shared::close_namespaces $wrap_parser) .
+                    nl ();
+
+  $section_manager->append_string ($code_string);
+  $section_manager->pop_entry;
+}
+
+sub _output_h_in_class ($$$$)
+{
+  my ($wrap_parser, $c_type, $c_class_type, $cpp_type) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $cpp_class_type = Common::Output::Shared::get_cpp_class_type $wrap_parser;
+  my $base_member = lc ($cpp_class_type) . '_';
+  my $virtual_dtor = 1;
+  my $copy_proto = 'no';
+  my $reinterpret = 1;
+  my $definitions = 1;
+  my $code_string = nl () .
+                    nl (Common::Output::Shared::doxy_skip_begin) .
+                    nl () .
+                    nl ('public:') .
+                    nl ('  typedef ' . $cpp_type . ' CppObjectType;') .
+                    nl ('  typedef ' . $cpp_class_type . ' CppClassType;') .
+                    nl ('  typedef ' . $c_type . ' BaseObjectType;') .
+                    nl ('  typedef ' . $c_class_type . ' BaseClassType;') .
+                    nl () .
+                    nl ('private:') .
+                    nl ('  friend class ' . $cpp_class_type . ';') .
+                    nl ('  static CppClassType ' . $base_member . ';') .
+                    nl () .
+                    nl ('  // noncopyable') .
+                    nl (Common::Output::Shared::copy_protos_str $cpp_type) .
+                    nl () .
+                    nl ('protected:') .
+                    nl ('  ' . $cpp_type . '(); // You must derive from this class.') .
+                    nl () .
+                    nl ('  /** Called by constructors of derived classes. Provide the result of') .
+                    nl ('   * the Class init() function to ensure that it is properly') .
+                    nl ('   * initialized.') .
+                    nl ('   *') .
+                    nl ('   * @param interface_class The Class object for the derived type.') .
+                    nl ('   */') .
+                    nl ('  explicit ' . $cpp_type . '(const Glib::Interface_class& interface_class);') .
+                    nl () .
+                    nl ('public:') .
+                    nl ('  // This is public so that C++ wrapper instances can be') .
+                    nl ('  // created for C instances of unwrapped types.') .
+                    nl ('  // For instance, if an unexpected C type implements the C interface.') .
+                    nl ('  explicit ' . $cpp_type . '(' . $c_type . '* castitem);') .
+                    nl () .
+                    nl (Common::Output::Shared::doxy_skip_end) .
+                    nl () .
+                    nl ('public:') .
+                    nl (Common::Output::Shared::dtor_proto_str $cpp_type, $virtual_dtor) .
+                    nl () .
+                    nl ('  static void add_interface(GType gtype_implementer);') .
+                    nl () .
+                    nl (Common::Output::Shared::doxy_skip_begin) .
+                    nl ('  static GType get_type() G_GNUC_CONST;') .
+                    nl ('  static GType get_base_type() G_GNUC_CONST;') .
+                    nl (Common::Output::Shared::doxy_skip_end) .
+                    nl () .
+                    nl (Common::Output::Shared::gobj_protos_str $c_type, $copy_proto, $reinterpret, $definitions) .
+                    nl () .
+                    nl ('private:') .
+                    nl ('  // import section_class2?') .
+                    nl () .
+                    nl ('public:') .
+                    nl ('  // import H_VFUNCS_AND_SIGNALS()') .
+                    nl ();
+  my $main_section = $wrap_parser->get_main_section;
+
+  $section_manager->append_string_to_section ($code_string, $main_section);
+}
+
+sub _output_h_after_first_namespace ($$)
+{
+  my ($wrap_parser, $c_type) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $result_type = 'refptr';
+  my $take_copy_by_default = 'no';
+  my $open_glib_namespace = 1;
+  my $const_function = 0;
+  my $conditional = Common::Output::Shared::wrap_proto $wrap_parser, $c_type, $result_type, $take_copy_by_default, $open_glib_namespace, $const_function;
+  my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::H_AFTER_FIRST_NAMESPACE;
+
+  $section_manager->append_conditional_to_section ($conditional, $section);
+}
+
+sub _output_p_h ($$$$)
+{
+  my ($wrap_parser, $c_type, $c_class_type, $cpp_parent_type) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $cpp_class_type = Common::Output::Shared::get_cpp_class_type $wrap_parser;
+  my $cpp_parent_class_type = $cpp_parent_type . '::CppClassType';
+  my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+  my $code_string = nl ('#include <glibmm/private/interface_p.h>') .
+                    nl () .
+                    nl (Common::Output::Shared::open_namespaces $wrap_parser) .
+                    nl () .
+                    nl ('class ' . $cpp_class_type . ' : public ' . $cpp_parent_class_type) .
+                    nl ('{') .
+                    nl ('public:') .
+                    nl ('  typedef ' . $full_cpp_type . ' CppObjectType;') .
+                    nl ('  typedef ' . $c_type . ' BaseObjectType;') .
+                    nl ('  typedef ' . $c_class_type . ' BaseClassType;') .
+                    nl ('  typedef ' . $cpp_parent_class_type . ' CppClassParent;') .
+                    nl () .
+                    nl ('  friend class ' . $full_cpp_type . ';') .
+                    nl () .
+                    nl ('  const Glib::Interface_Class& init();') .
+                    nl () .
+                    nl ('  static void iface_init_function(void* g_iface, void* iface_data);') .
+                    nl () .
+                    nl ('  static Glib::ObjectBase* wrap_new(GObject*);') .
+                    nl () .
+                    nl ('protected:') .
+                    nl ('  // Callbacks (default signal handlers):') .
+                    nl ('  // These will call the *_impl member methods, which will then call the existing default signal callbacks, if any.') .
+                    nl ('  // You could prevent the original default signal handlers being called by overriding the *_impl method.');
+  my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_H_CONTENTS;
+
+  $section_manager->push_section ($section);
+  $section_manager->append_string ($code_string);
+  $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_H_DEFAULT_SIGNAL_HANDLERS;
+  $section_manager->append_section ($section);
+  $code_string = nl () .
+                 nl () .
+                 nl ('  // Callbacks (virtual functions):');
+  $section_manager->append_string ($code_string);
+  $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_H_VFUNCS;
+  $section_manager->append_section ($section);
+  $code_string = nl () .
+                 nl ('};') .
+                 nl () .
+                 nl (Common::Output::Shared::close_namespaces $wrap_parser) .
+                 nl ();
+  $section_manager->append_string ($code_string);
+  $section_manager->pop_entry;
+}
+
+sub _output_cc ($$$$$$)
+{
+  my ($wrap_parser, $c_type, $c_parent_type, $cpp_type, $cpp_parent_type, $get_type_func) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $conditional = Common::Output::Shared::generate_conditional $wrap_parser;
+  my $no_wrap_function_var = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::NO_WRAP_FUNCTION;
+  my $complete_cpp_type = Common::Output::Shared::get_complete_cpp_type $wrap_parser;
+  my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_END;
+  my $code_string = nl ('namespace Glib') .
+                    nl ('{') .
+                    nl () .
+                    nl ('Glib::RefPtr< ' . $complete_cpp_type . '> wrap(' . $c_type . '* object, bool take_copy)') .
+                    nl ('{') .
+                    nl ('  return Glib::RefPtr< ' . $complete_cpp_type . ' >(dynamic_cast< ' . $complete_cpp_type . '* >(Glib::wrap_auto_interface< ' . $complete_cpp_type . ' >(static_cast<GObject*>(object), take_copy)));') .
+                    nl ('  // We use dynamic_cast<> in case of multiple inheritance.') .
+                    nl ('}') .
+                    nl () .
+                    nl ('} // namespace Glib') .
+                    nl ();
+
+  $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+  $section_manager->push_section ($section);
+  $section_manager->append_conditional ($conditional);
+  $section_manager->set_variable_for_conditional ($no_wrap_function_var, $conditional);
+
+  my $cpp_class_type = Common::Output::Shared::get_cpp_class_type $wrap_parser;
+  my $base_member = lc ($cpp_class_type) . '_';
+  my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+
+  $code_string = nl (Common::Output::Shared::open_namespaces $wrap_parser) .
+                 nl ($full_cpp_type . '::' . $cpp_type . '()') .
+                 nl (':') .
+                 nl ('  ' . $cpp_parent_type . '(' . $base_member . '.init())') .
+                 nl ('{}') .
+                 nl () .
+                 nl ($full_cpp_type . '::' . $cpp_type . '(' . $c_type . '* castitem)') .
+                 nl (':') .
+                 nl ('  ' . $cpp_parent_type . '(static_cast< ' . $c_parent_type . '* >(castitem))') .
+                 nl ('{}') .
+                 nl () .
+                 nl ($full_cpp_type . '::' . $cpp_type . '(const Glib::Interface_Class& interface_class)') .
+                 nl (':') .
+                 nl ('  ' . $cpp_parent_type . '(interface_class)') .
+                 nl ('{}') .
+                 nl () .
+                 nl ($full_cpp_type . '::~' . $cpp_type . '()') .
+                 nl ('{}') .
+                 nl () .
+                 nl ('// static') .
+                 nl ('void ' . $full_cpp_type . '::add_interface(GType gtype_implementer)') .
+                 nl ('{') .
+                 nl ('  ' . $base_member . '.init().add_interface(gtype_implementer);') .
+                 nl ('}') .
+                 nl () .
+                 nl ($full_cpp_type . '::CppClassType ' . $full_cpp_type . '::' . $base_member . '; // initialize static member') .
+                 nl () .
+                 nl ('GType ' . $full_cpp_type . '::get_type()') .
+                 nl ('{') .
+                 nl ('  return ' . $base_member . '.init().get_type();') .
+                 nl ('}') .
+                 nl ();
+  $section_manager->append_string ($code_string);
+# TODO: move to Shared?
+  $code_string = nl ($full_cpp_type . '::CppClassType ' . $full_cpp_type . '::' . $base_member . '; // Initialize static member') .
+                 nl () .
+                 nl ('GType ' . $full_cpp_type . '::get_type()') .
+                 nl ('{') .
+                 nl ('  return ' . $base_member . '.init().get_type();') .
+                 nl ('}') .
+                 nl ();
+  $section_manager->append_string ($code_string);
+  $conditional = Common::Output::Shared::generate_conditional ($wrap_parser);
+  $code_string = nl ('GType ' . $full_cpp_type . '::get_type(GTypeModule* module)') .
+                 nl ('{') .
+                 nl ('  return ' . $base_member . '.init(module).get_type();') .
+                 nl ('}') .
+                 nl ();
+
+  my $dynamic_gtype_registration_var = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::DYNAMIC_GTYPE_REGISTRATION;
+
+  $section_manager->append_string_to_conditional ($code_string, $conditional, 1);
+  $section_manager->append_conditional ($conditional);
+  $section_manager->set_variable_for_conditional ($dynamic_gtype_registration_var, $conditional);
+  $code_string = nl ('GType ' . $full_cpp_type . '::get_base_type()') .
+                 nl ('{') .
+                 nl ('  return ' . $get_type_func . '();') .
+                 nl ('}') .
+                 nl ();
+  $section_manager->append_string ($code_string);
+
+  my @sections =
+  (
+    (Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_NAMESPACE),
+    (Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_SIGNAL_PROXIES),
+    (Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_PROPERTY_PROXIES),
+    (Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_DEFAULT_SIGNAL_HANDLERS),
+    (Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_VFUNCS),
+    (Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_VFUNCS_CPP_WRAPPER),
+    (Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_CC_NAMESPACE)
+  );
+
+  foreach my $cc_section (@sections)
+  {
+    $section_manager->append_section ($cc_section);
+    $section_manager->append_string (nl);
+  }
+
+  $section_manager->append_string (Common::Output::Shared::close_namespaces ($wrap_parser));
+  $section_manager->pop_entry;
+}
+
+sub _output_p_cc ($$$)
+{
+  my ($wrap_parser, $c_type, $get_type_func) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+  my $cpp_class_type = Common::Output::Shared::get_class_type $wrap_parser;
+  my $code_string = nl ('const Glib::Interface_Class& ' . $cpp_class_type . '::init()') .
+                    nl ('{') .
+                    nl ('  if (!gtype) // create GType if necessary.') .
+                    nl ('  {') .
+                    nl ('    // Glib::Interface_Class has to know the interface init function') .
+                    nl ('    // in order to add interfaces to implementing types') .
+                    nl ('    class_init_func_ = &' . $cpp_class_type . '::iface_init_function;') .
+                    nl () .
+                    nl ('    // We can not derive from another interface and it is not necessary anyway.') .
+                    nl ('    gtype_ = ' . $get_type_func . '();') .
+                    nl ('  }') .
+                    nl () .
+                    nl ('  return *this;') .
+                    nl ('}') .
+                    nl () .
+                    nl ('void ' . $cpp_class_type . '::iface_init_function(void* g_iface, void*)') .
+                    nl ('{') .
+                    nl ('  BaseClassType* const klass(static_cast<BaseClassType*>(g_iface));') .
+                    nl () .
+                    nl ('  // This is just to avoid an "unused variable" warning when there are no vfuncs or signal handlers to connect.') .
+                    nl ('  // This is a temporary fix until I find out why I can not seem to derive a GtkFileChooser interface. murrayc') .
+                    nl ('  g_assert(klass != 0);') .
+                    nl ();
+  my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_CC_NAMESPACE;
+  my @cc_sections_inside_func =
+  (
+    (Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_CC_INIT_VFUNCS),
+    (Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_CC_INIT_DEFAULT_SIGNAL_HANDLERS),
+  );
+  my @cc_sections_outside_func =
+  (
+    (Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_CC_VFUNCS),
+    (Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_CC_DEFAULT_SIGNAL_HANDLERS)
+  );
+
+  $section_manager->push_section ($section);
+  $section_manager->append_string ($code_string);
+
+  foreach my $cc_section (@cc_sections_inside_func)
+  {
+    $section_manager->append_section ($cc_section);
+    $section_manager->append_string (nl);
+  }
+
+  $code_string = nl ('}') .
+                 nl ();
+  $section_manager->append_string ($code_string);
+
+  foreach my $cc_section (@cc_sections_outside_func)
+  {
+    $section_manager->append_section ($cc_section);
+    $section_manager->append_string (nl);
+  }
+
+  $code_string = nl ('Glib::ObjectBase* ' . $cpp_class_type . '::wrap_new(GObject* object)') .
+                 nl ('{') .
+                 nl ('  return new ' . $full_cpp_type . '(static_cast< ' . $c_type .' >(object));') .
+                 nl ('}');
+  $section_manager->append_string ($code_string);
+  $section_manager->pop_entry;
+}
+
+sub output ($$$$$$$)
+{
+  my ($wrap_parser, $c_type, $c_class_type, $c_parent_type, $cpp_type, $cpp_parent_type, $get_type_func) = @_;
+
+  _output_h_before_first_namespace $wrap_parser, $c_type, $c_class_type;
+  _output_h_in_class $wrap_parser, $c_type, $c_class_type, $cpp_type;
+  _output_h_after_first_namespace $wrap_parser, $c_type;
+  _output_p_h $wrap_parser, $c_type, $c_class_type, $cpp_parent_type;
+  _output_cc $wrap_parser, $c_type, $c_parent_type, $cpp_type, $cpp_parent_type, $get_type_func;
+  _output_cc_p $wrap_parser, $c_type, $get_type_func;
+}
+
+1; # indicate proper module load.
diff --git a/tools/pm/Common/Output/Method.pm b/tools/pm/Common/Output/Method.pm
new file mode 100644
index 0000000..fc71542
--- /dev/null
+++ b/tools/pm/Common/Output/Method.pm
@@ -0,0 +1,183 @@
+# -*- mode: perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# gmmproc - Common::Output::Method module
+#
+# Copyright 2012 glibmm development team
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+#
+
+package Common::Output::Method;
+
+use strict;
+use warnings;
+
+sub nl
+{
+  return Common::Output::Shared::nl @_;
+}
+
+sub _output_h ($$$$$$$)
+{
+  my ($wrap_parser, $static, $cpp_ret_type, $cpp_func_name, $cpp_param_types, $cpp_param_names, $const) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $main_section = $wrap_parser->get_main_section;
+  my $code_string = '';
+
+  die if (scalar (@{$cpp_param_types}) != scalar(@{$cpp_param_names}));
+  die if ($static and $const);
+
+  if ($static)
+  {
+    $code_string += 'static ';
+  }
+  $code_string += $cpp_ret_type . ' ' . $cpp_func_name;
+
+  my $cpp_params_str = Common::Output::Shared::paramzipstr $cpp_param_types, $cpp_param_names;
+
+  $code_string += '(' . $cpp_params_str . ')';
+  if ($const)
+  {
+    $code_string += ' const';
+  }
+  $code_string += ';';
+  $section_manager->append_string_to_section (nl ($code_string), $main_section);
+}
+
+sub _output_cc ($$$$$$$$$$$$$$$$)
+{
+  my ($wrap_parser, $static, $cpp_ret_type, $cpp_func_name, $cpp_param_types, $cpp_param_names, $const, $constversion, $deprecated, $ifdef, $c_ret_type, $ret_transfer, $c_func_name, $c_param_types, $c_param_transfers, $errthrow) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $code_string = '';
+  my $ret_void = ($cpp_ret_type eq 'void');
+
+# TODO: replace with exception throwing
+  # if dies then it is internal error. should not happen here.
+  die if ($static and ($const or $constversion));
+  die if (scalar (@{$types_list}) != scalar(@{$names_list}));
+  die if (scalar (@{$c_param_types}) != scalar(@{$types_list}));
+
+  if ($deprecated)
+  {
+    $code_string += Common::Output::Shared::deprecate_start $wrap_parser;
+  }
+  if ($ifdef)
+  {
+    $code_string += nl ('#ifdef ' . $ifdef);
+  }
+  if ($static)
+  {
+    $code_string += nl ('// static');
+  }
+
+  my $cpp_params_str = Common::Output::Shared::paramzipstr $cpp_param_types, $cpp_param_names;
+  my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+  my $c_type = Common::Output::Shared::get_c_type;
+
+  $code_string += nl ($cpp_ret_type . ' ' . $full_cpp_type . '::' . $cpp_func_name . '(' . $cpp_param_list_str . ')' . ($const ? ' const' : '')) .
+                  nl ('{');
+
+  my $names_only = join ', ', @{$cpp_param_names};
+
+  if ($constversion)
+  {
+    my $ret = '';
+
+    unless ($ret_void)
+    {
+      $ret = 'return ';
+    }
+    $code_string += nl ('  ' . $ret . 'const_cast< ' . $full_cpp_type . '* >(this)->' . $cpp_func_name . '(' . $names_only . ');');
+  }
+  else
+  {
+    my $this_param = '';
+
+    if ($const)
+    {
+      $this_param = 'const_cast< ' . $c_type . '* >(gobj()), ';
+    }
+    elsif (not $static)
+    {
+      $this_param = 'gobj(), ';
+    }
+
+    my $conversions_store = $wrap_parser->get_conversions_store;
+    my $c_param_list_str = $this_param . (Common::Output::Shared::convzipstr $cpp_param_types, $c_param_types, $c_param_transfers, $cpp_param_names) . ($errthrow ? ', &gerror' . '');
+    my $c_func_invocation = $c_func_name . '(' . $c_param_list_str . ')';
+    my $ret_convert = $conversions_store->get_conversion ($c_ret_type, $cpp_ret_type, $ret_transfer, $c_func_invocation);
+
+    if ($errthrow)
+    {
+      $code_string += nl ('  GError* gerror(0);');
+
+      unless ($ret_void)
+      {
+        $code_string += nl ('  ' . $cpp_ret_type . ' retvalue(' . $ret_convert . ');');
+      }
+      else
+      {
+        $code_string += nl () .
+                        nl ('  ' . $c_func_invocation . ';');
+      }
+      if ($errthrow)
+      {
+        $code_string += nl () .
+                        nl ('  if (gerror)') .
+                        nl ('  {') .
+                        nl ('    ::Glib::Error::throw_exception(gerror);') .
+                        nl ('  }');
+      }
+      unless ($ret_void)
+      {
+        $code_string += nl () .
+                        nl ('return retvalue;');
+      }
+    }
+    else
+    {
+      if ($ret_void)
+      {
+        $code_string += nl ('  return ' . $ret_convert . ';');
+      }
+      else
+      {
+        $code_string += nl ('  ' . $c_func_invocation . ';');
+      }
+    }
+  }
+  $code_string += nl ('}');
+  if ($ifdef)
+  {
+    $code_string += nl ('#endif // ' . $ifdef);
+  }
+  if ($deprecated)
+  {
+    $code_string += Common::Output::Shared::deprecate_end $wrap_parser;
+  }
+
+  my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_NAMESPACE;
+
+  $section_manager->append_string_to_section ($code_string, $section);
+}
+
+sub output ($$$$$$$$$$$$$$$$)
+{
+  my ($wrap_parser, $static, $cpp_ret_type, $cpp_func_name, $cpp_param_types, $cpp_param_names, $const, $constversion, $deprecated, $ifdef, $c_ret_type, $ret_transfer, $c_func_name, $c_param_types, $c_param_transfers, $errthrow) = @_;
+
+  _output_h $wrap_parser, $static, $cpp_ret_type, $cpp_func_name, $cpp_param_types, $cpp_param_names, $const;
+  _output_cc $wrap_parser, $static, $cpp_ret_type, $cpp_func_name, $cpp_param_types, $cpp_param_names, $const, $constversion, $deprecated, $ifdef, $c_ret_type, $ret_transfer, $c_func_name, $c_param_types, $c_param_transfers, $errthrow;
+}
+
+1; # indicate proper module load.
diff --git a/tools/pm/Common/Output/OpaqueCopyable.pm b/tools/pm/Common/Output/OpaqueCopyable.pm
new file mode 100644
index 0000000..0912b1c
--- /dev/null
+++ b/tools/pm/Common/Output/OpaqueCopyable.pm
@@ -0,0 +1,188 @@
+# -*- mode: perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# gmmproc - Common::Output::OpaqueCopyable module
+#
+# Copyright 2012 glibmm development team
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+#
+
+package Common::Output::OpaqueCopyable;
+
+use strict;
+use warnings;
+
+sub nl
+{
+  return Common::Output::Shared::nl @_;
+}
+
+sub _output_h_in_class ($$$)
+{
+  my ($wrap_parser, $c_type, $cpp_type) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $code_string = nl ('public:') .
+                    nl (Common::Output::Shared::doxy_skip_begin) .
+                    nl ('  typedef ' . $cpp_type . ' CppObjectType;') .
+                    nl ('  typedef ' . $c_type . ' BaseObjectType;') .
+                    nl (Common::Output::Shared::doxy_skip_end) .
+                    nl ();
+  my $main_section = $wrap_parser->get_main_section;
+
+  $section_manager->push_section ($main_section);
+  $section_manager->append_string ($code_string);
+
+  my $conditional = Common::Output::Shared::default_ctor_proto $wrap_parser, $cpp_type;
+
+  $section_manager->append_conditional ($conditional);
+
+  my $copy_proto = 'const';
+  my $reinterpret = 0;
+  my $definitions = 1;
+  my $virtual_dtor = 0;
+
+  $code_string = nl ('  // Use make_a_copy = true when getting it directly from a struct.') .
+                 nl ('  explicit ' . $cpp_type . '(' . $c_type . '* castitem, bool make_a_copy = false);') .
+                 nl () .
+                 nl (Common::Output::Shared::copy_protos_str $cpp_type) .
+                 nl () .
+                 nl (Common::Output::Shared::dtor_proto_str $cpp_type, $virtual_dtor) .
+                 nl () .
+                 nl (Common::Output::Shared::gobj_protos_str $c_type, $copy_proto, $reinterpret, $definitions) .
+                 nl () .
+                 nl ('protected:') .
+                 nl ('  ' . $c_type . '* gobject_;') .
+                 nl () .
+                 nl ('private:');
+  $section_manager->append_string ($code_string);
+  $section_manager->pop_entry;
+}
+
+sub _output_h_after_first_namespace ($$)
+{
+  my ($wrap_parser, $c_type) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $result_type = 'plain';
+  my $take_copy_by_default = 'no';
+  my $open_glib_namespace = 1;
+  my $const_function = 0;
+  my $conditional = Common::Output::Shared::wrap_proto $wrap_parser, $c_type, $result_type, $take_copy_by_default, $open_glib_namespace, $const_function;
+  my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::H_AFTER_FIRST_NAMESPACE;
+
+  $section_manager->append_conditional_to_section ($conditional, $section);
+}
+
+sub _output_cc ($$$$$$)
+{
+  my ($wrap_parser, $c_type, $cpp_type, $new_func, $copy_func, $free_func) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $custom_default_ctor_var = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::CUSTOM_DEFAULT_CTOR;
+  my $conditional = Common::Output::Shared::generate_conditional $wrap_parser;
+  my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+  my $code_string = nl ($full_cpp_type . '::' . $cpp_type . '()') .
+                    nl (':');
+  my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_END;
+
+  if (defined $new_func and $new_func ne '' and $new_func ne 'NONE')
+  {
+    $code_string += nl ('  gobject_(' . $new_func . '())');
+  }
+  else
+  {
+    $code_string += nl ('  gobject_(0) // Allows creation of invalid wrapper, e.g. for output arguments to methods.');
+  }
+  $code_string += nl ();
+  $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+  $section_manager->push_section ($section);
+  $section_manager->append_conditional ($conditional);
+  $section_manager->set_variable_for_conditional ($custom_default_ctor_var, $conditional);
+# TODO: we probably have to assume that copy func must be provided.
+  $code_string = nl ($full_cpp_type . '::' . $cpp_type . '(const ' . $cpp_type . '& src)') .
+                 nl (':') .
+                 nl ('  gobject_((src.gobject_) ? ' . $copy_func . '(src.gobject_) : 0)') .
+                 nl ('{}') .
+                 nl () .
+                 nl ($full_cpp_type . '::' . $cpp_type . '(' . $c_type . '* castitem, bool make_a_copy /* = false */)') .
+                 nl ('{') .
+                 nl ('  if (!make_a_copy)') .
+                 nl ('  {') .
+                 nl ('    // It was given to use by a function which has already made a copy for us to keep.') .
+                 nl ('    gobject_ = castitem;') .
+                 nl ('  }') .
+                 nl ('  else') .
+                 nl ('  {') .
+                 nl ('    // We are probably getting it via direct access to a struct,') .
+                 nl ('    // so we can not just take ut - we have to take a copy if it.') .
+                 nl ('    if (castitem)') .
+                 nl ('    {') .
+                 nl ('      gobject_ = ' . $copy_func . '(castitem);') .
+                 nl ('    }') .
+                 nl ('    else') .
+                 nl ('    {') .
+                 nl ('      gobject_ = 0;') .
+                 nl ('    }') .
+                 nl ('  }') .
+                 nl ('}') .
+                 nl ();
+  if (defined $copy_func and $copy_func ne '' and $copy_func ne 'NONE')
+  {
+    $code_string += nl ($full_cpp_type . '& ' . $full_cpp_type . '::operator=(const ' . $full_cpp_type . '& src)') .
+                    nl ('{') .
+                    nl ('  ' . $c_type . '* const new_gobject = (src.gobject_) ? ' . $copy_func . '(src.gobject_) : 0;') .
+                    nl () .
+                    nl ('  if (gobject_)') .
+                    nl ('  {') .
+                    nl ('    ' . $free_func . '(gobject_);') .
+                    nl ('  }') .
+                    nl () .
+                    nl ('  gobject_ = new_gobject;') .
+                    nl () .
+                    nl ('  return *this') .
+                    nl ('}') .
+                    nl ();
+  }
+  $code_string += nl ($full_cpp_type . '::~' . $cpp_type . '()') .
+                  nl ('{') .
+                  nl ('  if (gobject_)') .
+                  nl ('  {') .
+                  nl ('    ' . $free_func . '(gobject_);') .
+                  nl ('  }') .
+                  nl ('}') .
+                  nl () .
+                  nl ($c_type . '* ' . $full_cpp_type . '::gobj_copy() const') .
+                  nl ('{') .
+                  nl ('  return ' . $copy_func . '(gobject_);') .
+                  nl ('}') .
+                  nl ();
+  $section_manager->append_string ($code_string);
+
+  my $cc_namespace_section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_NAMESPACE;
+
+  $section_manager->append_section ($cc_namespace_section);
+  $code_string = nl () .
+                 Common::Output::Shared::close_namespaces $wrap_parser;
+  $section_manager->append_string ($code_string);
+  $section_manager->pop_entry;
+}
+
+sub output ($$$$$$)
+{
+  my ($wrap_parser, $c_type, $cpp_type, $new_func, $copy_func, $free_func) = @_;
+
+  _output_h_in_class $wrap_parser, $c_type, $cpp_type;
+  _output_h_after_first_namespace $wrap_parser, $c_type;
+  _output_cc $wrap_parser, $c_type, $cpp_type, $new_func, $copy_func, $free_func;
+}
+
+1; # indicate proper module load.
diff --git a/tools/pm/Common/Output/OpaqueRefcounted.pm b/tools/pm/Common/Output/OpaqueRefcounted.pm
new file mode 100644
index 0000000..1fbb278
--- /dev/null
+++ b/tools/pm/Common/Output/OpaqueRefcounted.pm
@@ -0,0 +1,191 @@
+# -*- mode: perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# gmmproc - Common::Output::OpaqueRefcounted module
+#
+# Copyright 2012 glibmm development team
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+#
+
+package Common::Output::OpaqueRefcounted;
+
+use strict;
+use warnings;
+
+sub nl
+{
+  return Common::Output::Shared::nl @_;
+}
+
+sub _output_h_in_class ($$$$)
+{
+  my ($wrap_parser, $c_type, $cpp_type, $new_func) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $code_string = nl ('public:') .
+                    nl (Common::Output::Shared::doxy_skip_begin) .
+                    nl ('  typedef ' . $cpp_type . ' CppObjectType;') .
+                    nl ('  typedef ' . $c_type . ' BaseObjectType;') .
+                    nl (Common::Output::Shared::doxy_skip_end) .
+                    nl ();
+
+  if (defined $new_func and $new_func ne '' and $new_func ne 'NONE')
+  {
+    $code_string += nl ('  static Glib::RefPtr< ' . $cpp_type . ' > create();') .
+                    nl ();
+  }
+
+  my $copy_proto = 'const';
+  my $reinterpret = 0;
+  my $definitions = 0;
+  my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+  my $main_section = $wrap_parser->get_main_section;
+
+  $code_string += nl ('  /** Increment the reference count for this object.') .
+                  nl ('   * You should never need to do this manually - use the object via a RefPtr instead.') .
+                  nl ('   */') .
+                  nl ('  void reference() const;') .
+                  nl () .
+                  nl ('  /** Decrement the reference count for this object.') .
+                  nl ('   * You should never need to do this manually - use the object via a RefPtr instead.') .
+                  nl ('   */') .
+                  nl ('  void unreference() const;') .
+                  nl () .
+                  nl (Common::Output::Shared::gobj_protos_str $c_type, $copy_proto, $reinterpret, $definitions) .
+                  nl () .
+                  nl ('protected:') .
+                  nl ('  // Do not derive this. ' . $full_cpp_type . ' can neither be constructed nor deleted.') .
+                  nl ('  ' . $cpp_type . '();') .
+                  nl ('  void operator delete(void*, size_t);') .
+                  nl () .
+                  nl ('private:') .
+                  nl (Common::Output::Shared::copy_protos_str $cpp_type) .
+                  nl ();
+  $section_manager->append_string_to_section ($code_string, $main_section);
+}
+
+sub _output_h_after_first_namespace ($$)
+{
+  my ($wrap_parser, $c_type) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $result_type = 'refptr';
+  my $take_copy_by_default = 'no';
+  my $open_glib_namespace = 1;
+  my $const_function = 0;
+# TODO: This should not be a conditional, but a plain string.
+  my $conditional = Common::Output::Shared::wrap_proto $wrap_parser, $c_type, $result_type, $take_copy_by_default, $open_glib_namespace, $const_function;
+  my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::H_AFTER_FIRST_NAMESPACE;
+
+  $section_manager->append_conditional_to_section ($conditional, $section);
+}
+
+sub _output_cc ($$$$$)
+{
+  my ($wrap_parser, $c_type, $new_func, $ref_func, $unref_func) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+  my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_END;
+  my $code_string = nl ('/* Why reinterpret_cast< ' . $full_cpp_type . '* >(gobject) is needed:') .
+                    nl (' *') .
+                    nl (' * A ' . $full_cpp_type . ' instance is in fact always a ' . $c_type . ' instance.') .
+                    nl (' * Unfortunately, ' . $c_type . ' cannot be a member of ' . $full_cpp_type . ',') .
+                    nl (' * because it is an opaque struct.  Also, the C interface does not provide') .
+                    nl (' * any hooks to install a destroy notification handler, thus we cannot') .
+                    nl (' * wrap it dynamically either.') .
+                    nl (' *') .
+                    nl (' * The cast works because ' . $full_cpp_type . ' does not have any member data, and') .
+                    nl (' * it is impossible to derive from it.  This is ensured by not implementing') .
+                    nl (' * the (protected) default constructor.  The ctor is protected rather than') .
+                    nl (' * private just to avoid a compile warning.') .
+                    nl (' */') .
+                    nl ('/* krnowak:') .
+                    nl (' * This is an awful hack and I think it is not necessary.') .
+                    nl (' * We could store a pointer to C instance.') .
+                    nl (' * We just would not be an owner of this pointer.') .
+                    nl (' */') .
+                    nl () .
+                    nl ('namespace Glib') .
+                    nl ('{') .
+                    nl () .
+                    nl ('Glib::RefPtr< ' . $full_cpp_type . ' > wrap(' . $c_type . '* object, bool take_copy)') .
+                    nl ('{') .
+                    nl ('  if (take_copy && object)') .
+                    nl ('    ' . $ref_func . '(object);') .
+                    nl () .
+                    nl ('  // See the comment at the top of this file, if you want to know why the cast works.') .
+                    nl ('  return Glib::RefPtr< ' . $full_cpp_type . ' >(reinterpret_cast< ' . $full_cpp_type . '* >(object));') .
+                    nl ('}') .
+                    nl () .
+                    nl ('} // namespace Glib') .
+                    nl () .
+                    nl (Common::Output::Shared::open_namespaces $wrap_parser) .
+                    nl ();
+  if (defined $new_func and $new_func ne '' and $new_func ne 'NONE')
+  {
+    $code_string += nl ('// static') .
+                    nl ('Glib::RefPtr< ' . $full_cpp_type . ' > ' . $full_cpp_type . '::create()') .
+                    nl ('{') .
+                    nl ('  // See the comment at the top of this file, if you want to know why the cast works.') .
+                    nl ('  return Glib::RefPtr< ' . $full_cpp_type . ' >(reinterpret_cast< ' . $full_cpp_type . ' >(' . $new_func . '()));') .
+                    nl ('}') .
+                    nl ();
+  }
+
+  $code_string += nl ('void ' . $full_cpp_type . '::reference() const') .
+                  nl ('{') .
+                  nl ('  // See the comment at the top of this file, if you want to know why the cast works.') .
+                  nl ('  ' . $ref_func . '(reinterpret_cast< ' . $c_type . '* >(const_cast< ' . $full_cpp_type .  '* >(this)));') .
+                  nl ('}') .
+                  nl () .
+                  nl ('void ' . $full_cpp_type . '::unreference() const') .
+                  nl ('{') .
+                  nl ('  // See the comment at the top of this file, if you want to know why the cast works.') .
+                  nl ('  ' . $unref_func . '(reinterpret_cast< ' . $c_type . '* >(const_cast< ' . $full_cpp_type . '* >(this)));') .
+                  nl ('}') .
+                  nl () .
+                  nl ($c_type . '* ' . $full_cpp_type . '::gobj()') .
+                  nl ('{') .
+                  nl ('  // See the comment at the top of this file, if you want to know why the cast works.') .
+                  nl ('  return reinterpret_cast< ' . $c_type . '* >(this);') .
+                  nl ('}') .
+                  nl () .
+                  nl ('const ' . $c_type . '* ' . $full_cpp_type . '::gobj() const') .
+                  nl ('{') .
+                  nl ('  // See the comment at the top of this file, if you want to know why the cast works.') .
+                  nl ('  return reinterpret_cast< const ' . $c_type . '* >(this);') .
+                  nl ('}') .
+                  nl () .
+                  nl ($c_type . '* ' . $full_cpp_type . '::gobj_copy() const') .
+                  nl ('{') .
+                  nl ('  // See the comment at the top of this file, if you want to know why the cast works.') .
+                  nl ('  ' . $c_type . '* const gobject = reinterpret_cast< ' . $c_type . '* >(const_cast< ' . $full_cpp_type . '* >(this));') .
+                  nl ('  ' . $ref_func . '(gobject);') .
+                  nl ('  return gobject;') .
+                  nl ('}') .
+                  nl ();
+  $section_manager->append_string_to_section ($code_string, $section);
+  $code_string = nl () .
+                 Common::Output::close_namespaces $wrap_parser;
+  $section_manager->append_string_to_section ($code_string, $section);
+}
+
+sub output ($$$$$$)
+{
+  my ($wrap_parser, $c_type, $cpp_type, $new_func, $ref_func, $unref_func) = @_;
+
+  _output_h_in_class $wrap_parser, $c_type, $cpp_type, $new_func;
+  _output_h_after_first_namespace $wrap_parser, $c_type;
+  _output_cc $wrap_parser, $c_type, $new_func, $ref_func, $unref_func;
+}
+
+1; # indicate proper module load.
diff --git a/tools/pm/Common/Output/Property.pm b/tools/pm/Common/Output/Property.pm
new file mode 100644
index 0000000..4fb5bda
--- /dev/null
+++ b/tools/pm/Common/Output/Property.pm
@@ -0,0 +1,97 @@
+# -*- mode: perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# gmmproc - Common::Output::Property module
+#
+# Copyright 2012 glibmm development team
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+#
+
+package Common::Output::Property;
+
+use strict;
+use warnings;
+
+sub nl
+{
+  return Common::Output::Shared::nl @_;
+}
+
+sub _output_h ($$$$)
+{
+  my ($wrap_parser, $proxy_suffix, $prop_cpp_type, $prop_cpp_name) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $main_section = $wrap_parser->get_main_section;
+  my $proxy_type = 'Glib::PropertyProxy' . $proxy_suffix . '< ' . $prop_cpp_type . ' >';
+  my $method_suffix = ($proxy_suffix eq '_ReadOnly' ? ' const' : '');
+  my $code_string = (nl '  /** You rarely need to use properties because there are get_and _set_ methods for almost all of them.') .
+                    (nl '   * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when') .
+                    (nl '   * the value of the property changes.') .
+                    (nl '   */') .
+                    (nl '  ' . $proxy_type . ' property_' . $prop_cpp_name . '()' . $method_suffixP);
+
+  $section_manager->append_string_to_section ($code_string, $main_section);
+}
+
+sub _output_cc ($$$$$)
+{
+  my ($wrap_parser, $proxy_suffix, $prop_cpp_type, $prop_cpp_name, $prop_c_name) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_PROPERTY_PROXIES;
+  my $proxy_type = 'Glib::PropertyProxy' . $proxy_suffix . '< ' . $prop_cpp_type . ' >';
+  my $method_suffix = ($proxy_suffix eq '_ReadOnly' ? ' const' : '');
+  my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+  my $code_string = (nl $proxy_type . ' ' . $full_cpp_type . '::property_' . $prop_cpp_name . '()' . $method_suffix) .
+                    (nl '{') .
+                    (nl '  ' . $proxy_type . '(this, "' . $prop_c_name'");') .
+                    (nl '}') .
+                    (nl);
+
+  $section_manager->append_string_to_section ($code_string, $section);
+}
+
+sub output ($$$$$$$)
+{
+  my ($wrap_parser, $construct_only, $readable, $writable, $prop_cpp_type, $prop_cpp_name, $prop_c_name) = @_;
+  my $read_only = 0;
+  my $write_only = 0;
+
+  if ($construct_only)
+  {
+    $read_only = 1;
+  }
+  elsif (not $readable)
+  {
+    $write_only = 1;
+  }
+  elsif (not $writable)
+  {
+    $read_only = 1;
+  }
+
+  my $proxy_suffix = ($read_only ? '_ReadOnly' : ($write_only ? '_WriteOnly' : ''));
+
+  _output_h $wrap_parser, $proxy_suffix, $prop_cpp_type, $prop_cpp_name;
+  _output_cc $wrap_parser, $proxy_suffix, $prop_cpp_type, $prop_cpp_name, $prop_c_name;
+
+  if (not $read_only and $readable)
+  {
+    $proxy_suffix = '_ReadOnly';
+
+    _output_h $wrap_parser, $proxy_suffix, $prop_cpp_type, $prop_cpp_name;
+    _output_cc $wrap_parser, $proxy_suffix, $prop_cpp_type, $prop_cpp_name, $prop_c_name;
+  }
+}
+
+1; # indicate proper module load.
diff --git a/tools/pm/Common/Output/Shared.pm b/tools/pm/Common/Output/Shared.pm
index 85b87cd..7b47dd9 100644
--- a/tools/pm/Common/Output/Shared.pm
+++ b/tools/pm/Common/Output/Shared.pm
@@ -22,23 +22,20 @@ package Common::Output::Shared;
 
 use strict;
 use warnings;
+use feature ':5.10';
 
 use constant
 {
-  'PROTECTED_GCLASS_VAR' => 'PROTECTED_GCLASS_BOOL_VARIABLE',
-  'DYNAMIC_GTYPE_REGISTRATION_VAR' => 'DYNAMIC_GTYPE_REGISTRATION_BOOL_VARIABLE',
-  'STRUCT_NOT_HIDDEN_VAR' => 'STRUCT_NOT_HIDDEN_BOOL_VARIABLE',
-  'NO_WRAP_FUNCTION_VAR' => 'NO_WRAP_FUNCTION_BOOL_VARIABLE',
-  'DO_NOT_DERIVE_GTYPE_VAR' => 'DO_NOT_DERIVE_GTYPE_BOOL_VARIABLE',
-  'CUSTOM_WRAP_NEW_VAR' => 'CUSTOM_WRAP_NEW_BOOL_VARIABLE',
-  'CUSTOM_CTOR_CAST_VAR' => 'CUSTOM_CTOR_CAST_BOOL_VARIABLE',
-  'DERIVES_INITIALLY_UNOWNED_VAR' => 'DERIVES_INITIALLY_UNOWNED_BOOL_VARIABLE',
-  'CUSTOM_DTOR_VAR' => 'CUSTOM_DTOR_BOOL_VARIABLE'
+  'FLAGS_TYPE' => 'Flags',
+  'ENUM_TYPE' => 'Enum',
 };
 
+use Common::Variables;
+use Common::Sections;
+
 sub nl
 {
-  return (shift or '') . "\n";
+  return join '', @_, "\n";
 }
 
 sub doxy_skip_begin ()
@@ -53,10 +50,11 @@ sub doxy_skip_end ()
 
 sub open_namespaces ($)
 {
-  my ($namespaces) = @_;
+  my ($wrap_parser) = @_;
+  my $namespaces = $wrap_parser->get_namespaces;
   my $code_string = '';
 
-  foreach my $opened_name (reverse @{$namespaces})
+  foreach my $opened_name (@{$namespaces})
   {
     $code_string .= nl ('namespace ' . $opened_name) .
                     nl ('{') .
@@ -67,10 +65,11 @@ sub open_namespaces ($)
 
 sub close_namespaces ($)
 {
-  my ($namespaces) = @_;
+  my ($wrap_parser) = @_;
+  my $namespaces = $wrap_parser->get_namespaces;
   my $code_string = '';
 
-  foreach my $closed_name (@{$namespaces})
+  foreach my $closed_name (reverse @{$namespaces})
   {
     $code_string .= nl ('} // namespace ' . $closed_name) .
                     nl ();
@@ -78,22 +77,525 @@ sub close_namespaces ($)
   return $code_string;
 }
 
-sub join_namespaces ($)
+# returns VteTerminal
+sub get_c_type ($)
+{
+  my ($wrap_parser) = @_;
+
+  return $wrap_parser->get_c_class;
+}
+
+# returns Terminal
+sub get_cpp_type ($)
+{
+  my ($wrap_parser) = @_;
+  my $classes = $wrap_parser->get_classes;
+
+  if (@{$classes})
+  {
+    return $classes->[-1];
+  }
+  return undef;
+}
+
+# returns Terminal, the difference is that it can also return Foo::Bar if Bar is
+# a class inside a Foo class
+sub get_full_cpp_type ($)
+{
+  my ($wrap_parser) = @_;
+  my $classes = $wrap_parser->get_classes;
+  my $full_cpp_class = join '::', @{$classes};
+
+  return $full_cpp_class;
+}
+
+# returns Gnome::Vte
+sub get_full_namespace ($)
+{
+  my ($wrap_parser) = @_;
+  my $namespaces = $wrap_parser->get_namespaces;
+  my $full_namespace = join '::', @{$namespaces};
+
+  return $full_namespace;
+}
+
+# returns Gnome::Vte::Terminal
+sub get_complete_cpp_type ($)
+{
+  my ($wrap_parser) = @_;
+  my $namespaces = get_full_namespace $wrap_parser;
+  my $classes = get_full_cpp_class $wrap_parser;
+
+  return join '::', $namespaces, $classes;
+}
+
+# returns Terminal_Class for Gnome::Vte::Terminal.
+# returns Terminal_Foo_Class for Gnome::Vte::Terminal::Foo.
+sub get_cpp_class_type ($)
 {
-  my ($namespaces) = @_;
+  my ($wrap_parser) = @_;
+  my $full_cpp_type = get_full_cpp_type $wrap_parser;
 
-  return join ('::', reverse @{$namespaces});
+  $full_cpp_type =~ s/::/_/g;
+  return $full_cpp_type . '_Class';
 }
 
-sub create_class_local_prefix ($$)
+# returns Gnome::Vte::Terminal_Class for Gnome::Vte::Terminal.
+# returns Gnome::Vte::Terminal_Foo_Class for Gnome::Vte::Terminal::Foo.
+sub get_complete_cpp_class_type ($)
 {
-  my ($namespaces, $class) = @_;
-  my $single_string = join_namespaces ($namespaces) . '_' . $class;
+  my ($wrap_parser) = @_;
+  my $full_namespace = get_full_namespace $wrap_parser;
+  my $cpp_class_type = get_cpp_class_type $wrap_parser;
 
-  $single_string =~ s/\W+/_/g;
-  $single_string =~ s/_+/_/g;
-  return uc ($single_string) . '_';
+  return join '::', $full_namespace, $cpp_class_type;
 }
 
+# TODO: implement beautifying if I am really bored.
+sub convert_members_to_strings ($)
+{
+  my ($members) = @_;
+  my @strings = ();
+
+  foreach my $pair (@{$members})
+  {
+    my $name = $pair->[0];
+    my $value = $pair->[1];
+
+    push @strings, '    ' . $name . ' = ' . $value;
+  }
+  return \ strings;
+}
+
+sub get_section ($$);
+sub get_variable ($$);
+
+sub output_enum_gtype_func_h ($$$$)
+{
+  my ($wrap_parser, $cpp_type, $type, $get_type_func) = @_;
+
+  if (defined $get_type_func)
+  {
+    my $namespaces = $wrap_parser->get_namespaces;
+    my $main_section = $wrap_parser->get_main_section;
+    my $classes = $wrap_parser->get_classes;
+    my $full_cpp_type = join '::', (get_full_cpp_type $wrap_parser), $cpp_type;
+    my $close = 1;
+    my $value_base = 'Glib::Value_' . $type;
+    my $code_string = '';
+    my $section_manager = $wrap_parser->get_section_manager;
+
+    if (@{$namespaces} == 1 and $namespaces->[0] eq 'Glib')
+    {
+      $close = 0;
+    }
+
+    if ($close)
+    {
+      $code_string .= close_namespaces ($wrap_parser) .
+                      nl (doxy_skip_begin) .
+                      nl ('namespace Glib') .
+                      nl ('{') .
+                      nl ();
+    }
+    else
+    {
+      $code_string .= nl (doxy_skip_begin);
+    }
+
+    $code_string .= nl ('template <>') .
+                    nl ('class Value< ' . $full_cpp_type . ' > : public ' . $value_base . '< ' . $full_cpp_type . ' >') .
+                    nl ('{') .
+                    nl ('public:') .
+                    nl ('  static GType value_type() G_GNUC_CONST;') .
+                    nl ('};') .
+                    nl ();
+
+    if ($close)
+    {
+      $code_string .= nl ('} // namespace Glib') .
+                      nl (doxy_skip_end) .
+                      nl () .
+                      open_namespaces ($wrap_parser);
+    }
+    else
+    {
+      $code_string .= nl (doxy_skip_end) .
+                      nl ();
+    }
+
+    if (@{$classes} > 0)
+    {
+      my $section = get_section $wrap_parser, Common::Sections::H_AFTER_FIRST_CLASS;
+
+      $section_manager->append_string_to_section ($code_string, $section);
+    }
+    else
+    {
+      $section_manager->append_string_to_section ($code_string, $main_section);
+    }
+  }
+}
+
+sub output_enum_gtype_func_cc ($$$)
+{
+  my ($wrap_parser, $cpp_type, $get_type_func) = @_;
+
+  if (defined $get_type_func)
+  {
+    my $container_cpp_type = get_full_cpp_type $wrap_parser;
+    my $full_cpp_type = join '::', $container_cpp_type, $cpp_type;
+    my $section_manager = $wrap_parser->get_section_manager;
+    my $code_string = nl ('namespace Glib') .
+                      nl ('{') .
+                      nl () .
+                      nl ('// static') .
+                      nl ('GType Glib::Value< ' . $full_cpp_type . ' >::value_type()') .
+                      nl ('{') .
+                      nl ('  return ' . $get_type_func . '();') .
+                      nl ('}') .
+                      nl () .
+                      nl ('} // namespace Glib') .
+                      nl ();
+    my $section = get_section $wrap_parser, Common::Sections::CC_END;
+
+    $section_manager->append_string_to_section ($code_string, $section);
+  }
+}
+
+sub generate_conditional ($)
+{
+  my ($wrap_parser) = @_;
+  my $number = $wrap_parser->get_number;
+
+  return 'CONDITIONAL#' . $number;
+}
+
+sub struct_prototype ($$$)
+{
+  my ($wrap_parser, $c_name, $c_class_name) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $code_string = nl (doxy_skip_begin) .
+                    nl ('typedef struct _' . $c_name . ' ' . $c_name . ';') .
+                    nl ('typedef struct _' . $c_class_name . ' ' . $c_class_name . ';') .
+                    nl (doxy_skip_end) .
+                    nl ();
+  my $variable = get_variable $wrap_parser, Common::Variables::STRUCT_NOT_HIDDEN;
+  my $conditional = generate_conditional $wrap_parser;
+
+  $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+  $section_manager->set_variable_for_conditional ($variable, $conditional);
+
+  return $conditional;
+}
+
+sub wrap_proto ($$$$$$)
+{
+  my ($wrap_parser, $c_name, $result_type, $take_copy, $open, $const) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $result = undef;
+  my $full_cpp_name = get_full_cpp_name $wrap_parser;
+
+# TODO: make result type constant
+  if ($result_type eq 'refptr')
+  {
+    $result = 'Glib::RefPtr< ' . $full_cpp_name . ' >';
+  }
+  elsif ($result_type eq 'ref')
+  {
+    $result = $full_cpp_name . '&';
+  }
+  elsif ($result_type eq 'ptr')
+  {
+    $result = $full_cpp_name . '*';
+  }
+  elsif ($result_type eq 'plain')
+  {
+    $result = $full_cpp_name;
+  }
+  else
+  {
+    die;
+  }
+
+  if ($const)
+  {
+    $result = 'const ' . $result;
+  }
+
+  my $params = ($const ? 'const ' : '') . $c_name . '* object';
+  my $params_doc = ' * @param object The C instance.';
+
+  if ($take_copy ne 'N/A')
+  {
+    $params_doc = nl ($params_doc) .
+                  nl (' * @param take_copy @c false if the result should take ownership') .
+                  ' * of the C instance. @c true if it should take a new copy or reference.';
+    $params += ', bool take_copy = ';
+    if ($take_copy eq 'yes')
+    {
+      $params += 'true';
+    }
+    elsif ($take_copy eq 'no')
+    {
+      $params += 'false';
+    }
+    else
+    {
+      die;
+    }
+  }
+
+  my $conditional = generate_conditional $wrap_parser;
+  my $variable = get_variable $wrap_parser, Common::Variables::NO_WRAP_FUNCTION;
+  my $code_string = '';
+
+  if ($open)
+  {
+    $code_string += nl ('namespace Glib') .
+                    nl ('{') .
+                    nl ();
+  }
+
+  $code_string += nl ('/** A Glib::wrap() method for this object.') .
+                  nl (' *') .
+                  nl ($params_doc) .
+                  nl (' * @result A C++ instance that wraps this C instance') .
+                  nl (' *') .
+                  nl (' * @relates ' . $full_cpp_name) .
+                  nl (' */') .
+                  nl ($result . ' wrap(' . $params . ');') .
+                  nl ();
+  if ($open)
+  {
+    $code_string += nl ('} //namespace Glib') .
+                    nl ();
+  }
+
+  $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+  $section_manager->set_variable_for_conditional ($variable, $conditional);
+
+  return $conditional;
+}
+
+sub default_ctor_proto ($$)
+{
+  my ($wrap_parser, $cpp_name) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $variable = get_variable $wrap_parser, Common::Variables::CUSTOM_DEFAULT_CTOR;
+  my $conditional = generate_conditional $wrap_parser;
+  my $code_string = nl ('  ' . $cpp_name . '();');
+
+  $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+  $section_manager->set_variable_for_conditional ($variable, $conditional);
+
+  return $conditional;
+}
+
+# wrap output of this function with nl();
+sub copy_protos_str ($)
+{
+  my ($cpp_name) = @_;
+  my $code_string = nl ('  ' . $cpp_name . '(const ' . $cpp_name . '& src);') .
+                    '  ' . $cpp_name . '& operator=(const ' . $cpp_name . '& src);';
+
+  return $code_string;
+}
+
+sub dtor_proto_str ($$)
+{
+  my ($cpp_name, $virtual_dtor) = @_;
+  my $code_string = '  ' . ($virtual_dtor ? 'virtual ' : '') . '~' . $cpp_name . '();';
+
+  return $code_string;
+}
+
+sub gobj_protos_str ($$$$)
+{
+  my ($c_name, $copy_proto, $reinterpret, $definitions) = @_;
+  my $gobj = ($reinterpret ? 'reinterpret_cast< ' . $c_name . '* >(gobject_)' : 'gobject_');
+  my $code_string = nl ('  /// Provides access to the underlying C instance.') .
+                    nl ('  ' . $c_name . '* gobj()' . ($definitions ? ' { return ' . $gobj . '; }' : ';')) .
+                    nl () .
+                    nl ('  /// Provides access to the underlying C instance.') .
+                    '  const ' . $c_name . '* gobj() const' . ($definitions ? ' { return ' . $gobj . '; }' : ';');
+
+  if ($copy_proto ne 'no')
+  {
+    $code_string = nl ($code_string) .
+                   nl () .
+                   nl ('  /// Provides access to the underlying C instance. The caller is responsible for freeing it. Use when directly setting fields in structs.') .
+                   '  ' . $c_name . '* gobj_copy()';
+    if ($copy_proto eq 'const')
+    {
+      $code_string += ' const';
+    }
+    elsif ($copy_proto ne 'yes')
+    {
+      die;
+    }
+    $code_string += ';';
+  }
+  return $code_string;
+}
+
+sub _get_prefixed_name ($$$)
+{
+  my ($wrap_parser, $name, $name_type) = @_;
+  my $prefixed_name = undef;
+
+  given ($name_type)
+  {
+    when (Common::Constants::CLASS)
+    {
+      my $complete_type = get_complete_cpp_type $wrap_parser;
+
+      $complete_type =~ s/::/_/g;
+      $prefixed_name = join '_', $complete_type, $name;
+    }
+    when (Common::Constants::NAMESPACE)
+    {
+      my $full_namespace = get_full_namespace $wrap_parser;
+
+      $full_namespace =~ s/::/_/g;
+      $prefixed_name = join '_', $full_namespace, $name;
+    }
+    when (Common::Constants::FILE)
+    {
+      $prefixed_name = $name;
+    }
+    when (Common::Constants::FIRST_NAMESPACE)
+    {
+      my $first_namespace = get_first_namespace $wrap_parser;
+      my $first_namespace_number = $wrap_parser->get_first_namespace_number;
+
+      $prefixed_name = join '_', $first_namespace, $first_namespace_number, $name;
+    }
+    when (Common::Constants::FIRST_CLASS)
+    {
+      my $full_namespace = get_full_namespace $wrap_parser;
+      my $first_class = get_first_class $wrap_parser;
+      my $first_class_number = $wrap_parser->get_first_class_number;
+
+      $full_namespace =~ s/::/_/g;
+
+      $prefixed_name = join '_', $full_namespace, $first_class, $first_class_number, $name;
+    }
+    default
+    {
+      die;
+    }
+  }
+
+  return $prefixed_name;
+}
+
+sub get_variable ($$)
+{
+  my ($wrap_parser, $variable) = @_;
+
+  return _get_prefixed_name $wrap_parser, $variable->[0], $variable->[1];
+}
+
+sub get_section ($$)
+{
+  my ($wrap_parser, $section) = @_;
+
+  return _get_prefixed_name $wrap_parser, $section->[0], $section->[1];
+}
+
+sub ifdef ($)
+{
+  my ($ifdef) = @_;
+
+  if ($ifdef)
+  {
+    my $str = nl ('#ifdef ' . $ifdef) .
+              nl ();
+
+    return $str;
+  }
+
+  return '';
+}
+
+sub endif ($)
+{
+  my ($ifdef) = @_;
+
+  if ($ifdef)
+  {
+    my $str = nl ('#endif // ' . $ifdef) .
+              nl();
+
+    return $str;
+  }
+
+  return '';
+}
+
+sub paramzipstr ($$)
+{
+  my ($array1, $array2) = @_;
+  my $count = @{$array1};
+
+# TODO: throw runtime error or internal error or whatever.
+  die if $count != scalar(@{$array2});
+  return join ', ', map { join ' ', $array1->[$_], $array2->[$_] } 0 .. $count;
+}
+
+sub get_parent_from_object ($$)
+{
+  my ($wrap_parser, $object) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $variable = get_variable $wrap_parser, Common::Variables::IS_INTERFACE;
+  my $code_string = '';
+
+  if ($section_manager->get_variable ($variable))
+  {
+    $code_string = (nl 'g_type_interface_peek_parent( // Get the parent interface of the interface (The original underlying C inteface)') .
+                   (nl '    g_type_interface_peek(G_OBJECT_GET_CLASS(', $object, '), CppObjectType::get_type()) // Get the interface.') .
+                       '    )';
+  }
+  else
+  {
+    $code_string = 'g_type_class_peek_parent(G_OBJECT_GET_CLASS(' . $object . ')) // Get the parent class of the object class (The original underlying C class).';
+  }
+
+  return $code_string;
+}
+
+sub convzipstr ($$$$$)
+{
+  my ($wrap_parser, $from_types, $to_types, $transfers, $from_names) = @_;
+  my $conversions_store = $wrap_parser->get_conversions_store;
+  my $from_types_count = @{$from_types};
+  my $to_types_count = @{$to_types};
+  my $transfers_count = @{$transfers};
+  my $from_names_count = @{$from_names};
+
+# TODO: throw runtime error or internal error or whatever.
+  die if $from_types_count != $to_types_count or $to_types_count != $transfers_count or $transfers_count != $from_names_count;
+  return join ', ', map { $conversions_store->get_conversion ($from_types->[$_], $to_types->[$_], $transfers->[$_], $from_names->[$_]) } 0 .. $from_types_count;
+}
+
+sub deprecate_start ($)
+{
+  my ($wrap_parser) = @_;
+  my $mm_module = $wrap_parser->get_mm_module;
+
+  return (nl '#ifdef ' . (uc $mm_module) . '_DISABLE_DEPRECATED') .
+         (nl);
+}
+
+sub deprecate_end ($)
+{
+  my ($wrap_parser) = @_;
+  my $mm_module = $wrap_parser->get_mm_module;
+
+  return (nl '#endif // ' . (uc $mm_module) . '_DISABLE_DEPRECATED') .
+         (nl);
+
+}
 
 1; # indicate proper module load.
diff --git a/tools/pm/Common/Output/Signal.pm b/tools/pm/Common/Output/Signal.pm
new file mode 100644
index 0000000..f1ffd92
--- /dev/null
+++ b/tools/pm/Common/Output/Signal.pm
@@ -0,0 +1,359 @@
+# -*- mode: perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# gmmproc - Common::Output::Signal module
+#
+# Copyright 2012 glibmm development team
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+#
+
+package Common::Output::Signal;
+
+use strict;
+use warnings;
+
+sub nl
+{
+  return Common::Output::Shared::nl @_;
+}
+
+sub _output_h ($$$$$$)
+{
+  my ($wrap_parser, $ifdef, $cpp_return_type, $cpp_signal_name, $cpp_param_types, $default_signal_handler_enabled) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $main_section = $wrap_parser->get_main_section;
+  my $cpp_param_types_str = join ', ', @{$cpp_param_types};
+  my $code_string = (Common::Output::Shared::ifdef $ifdef) .
+                    nl ('  Glib::SignalProxy' . (scalar @{$cpp_param_types}) . '< ' . $cpp_return_type . ', ' . $cpp_param_types_str . ' > signal_' . $cpp_signal_name . '();') .
+                    nl () .
+                    Common::Output::Shared::endif $ifdef;
+
+  $section_manager->append_string_to_section ($code_string, $main_section);
+
+  if ($default_signal_handler_enabled)
+  {
+    $code_string = (Common::Output::Shared::ifdef $ifdef) .
+                   nl ('  virtual ' . $cpp_return_type . ' on_' . $cpp_signal_name . '(' . $cpp_param_types_str . ');') .
+                   nl () .
+                   Common::Output::Shared::endif $ifdef;
+
+    my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::H_DEFAULT_SIGNAL_HANDLERS;
+
+    $section_manager->append_string_to_section ($code_string, $section);
+  }
+}
+
+sub _output_p_h ($$$$$$$)
+{
+  my ($wrap_parser, $ifdef, $c_return_type, $c_signal_name, $c_param_types, $c_param_names, $default_signal_handler_enabled) = @_;
+
+  if ($default_signal_handler_enabled)
+  {
+    my $section_manager = $wrap_parset->get_section_manager;
+    my $c_params_str = Common::Output::Shared::paramzipstr $c_param_types, $c_param_names;
+    my $code_string = (Common::Output::Shared::ifdef $ifdef) .
+                      nl ('  static ' . $c_return_type . ' ' . $c_signal_name . '_callback(' . $c_params_str . ');') .
+                      nl () .
+                      Common::Output::Shared::endif $ifdef;
+    my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_H_DEFAULT_SIGNAL_HANDLERS;
+
+    $section_manager->append_string_to_section ($code_string, $section);
+  }
+}
+
+sub _output_cc ($$$$$$$$$$$$$$)
+{
+  my ($wrap_parser, $ifdef, $c_return_type, $c_return_transfer, $c_signal_name, $c_signal_string, $c_param_types, $c_param_names, $c_param_transfers, $cpp_return_type, $cpp_signal_name, $cpp_param_types, $custom_c_callback, $default_signal_handler_enabled) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+  my $signal_prefix = $full_cpp_type;
+  my $c_type = Common::Output::Shared::get_c_type $wrap_parser;
+
+  $signal_prefix =~ s/::/_/g;
+
+  my $proxy_info = $signal_prefix . '_signal_' . $cpp_signal_name . '_info';
+  my $ret_void = ($c_return_type eq 'void');
+  my $cpp_param_types_str = join ', ', @cpp_param_types;
+  my $conversions_store = $wrap_parser->get_conversions_store;
+  my $code_string = Common::Output::Shared::ifdef $ifdef;
+
+  if ($ret_void and not @{$c_param_types} and $cpp_return_type eq 'void' and not @{$cpp_param_types})
+  {
+    $code_string += nl ('// Use predefined callback for SignalProxy0<void> to reduce code size.') .
+                    nl ('const Glib::SignalProxyInfo ' . $proxy_info . ' =') .
+                    nl ('{') .
+                    nl ('  ' . $c_signal_string . ',') .
+                    nl ('  G_CALLBACK(&Glib::SignalProxyNormal::slot0_void_callback),') .
+                    nl ('  G_CALLBACK(&Glib::SignalProxyNormal::slot0_void_callback)') .
+                    nl ('};') .
+                    nl ();
+  }
+  else
+  {
+    my $signal_callback = $signal_prefix . '_signal_' . $cpp_signal_name . '_callback';
+    my $signal_notify = undef;
+
+    if ($ret_void)
+    {
+      $signal_notify = $signal_callback;
+    }
+    else
+    {
+      $signal_notify = $signal_prefix . '_signal_' . $cpp_signal_name . '_notify_callback';
+    }
+    unless ($custom_c_callback)
+    {
+      my $callback_cpp_params_str = Common::Output::Shared::convzipstr $wrap_parser, $c_param_types, $cpp_param_types, $c_param_transfers, $c_param_names;
+      my $c_params_str = Common::Output::Shared::paramzipstr $c_param_types, $c_param_names;
+      my $partial_return_string = '(*static_cast<SlotType*>(slot))(' . $callback_cpp_params_str . ')';
+      my $return_string = $partial_return_string;
+      my $last_return = '';
+
+      unless ($ret_void)
+      {
+        if ($c_return_transfer == Common::ConversionsStore and $c_return_type =~ /\*$/)
+        {
+# TODO: print a warning - pointers returned from signals ought to have ownership transferred fully.
+# TODO continued: need warning or error with fixed line number for this.
+        }
+        my $conv = $conversions_store->get_conversion ($cpp_return_type, $c_return_type, $c_return_transfer, $return_string);
+
+        $return_string = 'return ' . $conv;
+        $last_return = nl () .
+                       nl ('  typedef ' . $c_return_type . ' RType;') .
+                       nl ('  return RType();');
+      }
+      $code_string += nl ($c_return_type . ' ' . $signal_callback . '(' . $c_type . '* self, ' . $c_params_str . ', gpointer data)') .
+                      nl ('{') .
+                      nl ('  using namespace ' . (Common::Output::Shared::get_full_namespace $wrap_parser) . ';') .
+                      nl ('  typedef sigc::slot< ' . $cpp_return_type . ', ' . $cpp_param_types_str . ' > SlotType;') .
+                      nl () .
+                      nl ('  // Do not try to call a signal on a disassociated wrapper.') .
+                      nl ('  if (Glib::ObjectBase::_get_current_wrapper(static_cast<GObject*>(self)))') .
+                      nl ('  {') .
+                      nl ('    try') .
+                      nl ('    {') .
+                      nl ('      sigc::slot_base* const slot(Glib::SignalProxyNormal::data_to_slot(data));') .
+                      nl () .
+                      nl ('      if (slot)') .
+                      nl ('      {') .
+                      nl ('        ' . $return_string . ';') .
+                      nl ('      }') .
+                      nl ('    }') .
+                      nl ('    catch (...)') .
+                      nl ('    {') .
+                      nl ('      Glib::exception_handlers_invoke();') .
+                      nl ('    }') .
+                      nl ('  }') .
+                      nl ($last_return . '}') .
+                      nl ();
+      unless ($ret_void)
+      {
+        $code_string += nl ($c_return_type . ' ' . $signal_notify . '(' . $c_type . '* self, ' . $c_params_str . ', gpointer data)') .
+                        nl ('{') .
+                        nl ('  using namespace ' . (Common::Output::Shared::get_full_namespace $wrap_parser) . ';') .
+                        nl ('  typedef sigc::slot< void, ' . $cpp_param_types_str . ' > SlotType;') .
+                        nl () .
+                        nl ('  // Do not try to call a signal on disassociated wrapper.') .
+                        nl ('  if (Glib::ObjectBase::_get_current_wrapper(static_cast<GObject*>(self)))') .
+                        nl ('  {') .
+                        nl ('    try') .
+                        nl ('    {') .
+                        nl ('      if (sigc::slot_base* const slot = Glib::SignalProxyNormal::data_to_slot(data))') .
+                        nl ('      {') .
+                        nl ('        ' . $partial_return_string . ';') .
+                        nl ('      }') .
+                        nl ('    }') .
+                        nl ('    catch (...)') .
+                        nl ('    {') .
+                        nl ('      Glib::exception_handlers_invoke();') .
+                        nl ('    }') .
+                        nl ('  }') .
+                        nl () .
+                        nl ('  typedef ' . $c_return_type . ' RType;') .
+                        nl ('  return RType();') .
+                        nl ('}') .
+                        nl ();
+      }
+    }
+    $code_string += nl ('const Glib::SignalProxyInfo ' . $proxy_info . ' =') .
+                    nl ('{') .
+                    nl ('  ' . $c_signal_string . ',') .
+                    nl ('  G_CALLBACK(&' . $signal_callback . '),') .
+                    nl ('  G_CALLBACK(&' . $signal_notify . ')') .
+                    nl ('};') .
+                    nl ();
+  }
+
+  $code_string += Common::Output::Shared::endif $ifdef;
+
+  my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_UNNAMED_NAMESPACE;
+
+  $section_manager->append_string_to_section ($code_string, $section);
+
+  my $signal_proxy_type = 'Glib::SignalProxy' . (scalar @{$cpp_param_types}) . '< ' . $cpp_return_type . ', ' . $cpp_param_types_str . ' >';
+
+  $code_string = (Common::Output::Shared::ifdef $ifdef) .
+                 nl ($signal_proxy_type . ' ' . $full_cpp_type . '::signal_' . $cpp_signal_name . '()') .
+                 nl ('{') .
+                 nl ('  ' . $signal_proxy_type . '(this, &' . $proxy_info . ');') .
+                 nl ('}') .
+                 nl () .
+                 Common::Output::Shared::endif $endif;
+  $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_SIGNAL_PROXIES;
+  $section_manager->append_string_to_section ($code_string, $section);
+
+  if ($default_signal_handler_enabled)
+  {
+    $code_string = Common::Output::Shared::ifdef $ifdef;
+
+    my $parent_from_object = Common::Output::Shared::get_parent_from_object $wrap_parser, 'gobject_';
+    my $cpp_params_str = Common::Output::paramzipstr $cpp_param_types, $cpp_param_names;
+    my $cpp_to_c_params_str = Common::Output::Shared::convzipstr $cpp_param_types, $c_param_types, $c_param_transfers, $cpp_param_names;
+    my $c_func_invocation = '(*base->' . $c_signal_name . ')(gobj(), ' . $cpp_to_c_params_str . ')';
+    my $last_return = '';
+
+    $code_string += nl ($cpp_return_type . ' ' . $full_cpp_type . '::on_' . $cpp_signal_name . '(' . $cpp_params_str . ')') .
+                    nl ('{') .
+                    nl ('  BaseClassType* const base(static_cast<BaseClassType*>(' . $parent_from_object . '));') .
+                    nl () .
+                    nl ('  if (base && base->' . $c_signal_name . ')') .
+                    nl ('  {');
+
+    if ($ret_void)
+    {
+      $code_string += nl ('    ' . $c_func_invocation . ';') .
+    }
+    else
+    {
+      my $conv = $conversions_store->get_conversion ($c_return_type, $cpp_return_type, $c_return_transfer, $c_func_invocation);
+
+      $code_string += nl ('    return ' . $conv . ';');
+      $last_return = nl () .
+                     nl ('  typedef ' . $cpp_return_type . ' RType;') .
+                     nl ('  return RType();');
+
+    }
+
+    $code_string += nl ('  }') .
+                    nl($last_return . '}') .
+                    Common::Output::Shared::endif $ifdef;
+
+    $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_DEFAULT_SIGNAL_HANDLERS;
+    $section_manager->append_string_to_section ($code_string, $section);
+  }
+}
+
+sub _output_p_cc ($$$$$$$$$$$$$)
+{
+  my ($wrap_parser, $ifdef, $c_return_type, $c_return_transfer, $c_signal_name, $c_param_types, $c_param_names, $c_param_transfers, $cpp_return_type, $cpp_signal_name, $cpp_param_types, $default_signal_handler_enabled) = @_;
+
+  if ($default_signal_handler_enabled)
+  {
+    my $section_manager = $wrap_parser->get_section_manager;
+    my $cpp_class_type = Common::Output::Shared::get_cpp_class_type $wrap_parser;
+    my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_CC_INIT_DEFAULT_SIGNAL_HANDLERS;
+    my $code_string = (Common::Output::Shared::ifdef $ifdef) .
+                      nl ('  klass->' . $c_signal_name . ' = &' . $c_signal_name . '_callback;') .
+                      nl () .
+                      Common::Output::Shared::endif $ifdef;
+
+    $section_manager->append_string_to_section ($code_string, $section);
+
+    my $c_params_str = Common::Output::Shared::zupstr $c_param_types, $c_param_names, ' ', ', ';
+    my $ret_void = ($c_return_type eq 'void');
+    my $conversions_store = $wrap_parser->get_conversions_store;
+    my $convs_str = Common::Output::Shared::convzipstr $c_param_types, $cpp_param_types, $c_param_transfers, $c_param_names;
+    my $vfunc_call = 'obj->on_' . $cpp_signal_name . '(' . $convs_str . ')';
+    my $c_callback_call = '(*base->' . $c_signal_name . '(self, ' . (join ', ', @{$c_param_names}) . ')';
+    my $last_return = '';
+
+    unless ($ret_void)
+    {
+      $vfunc_call = 'return ' . $conversions_store->get_conversion ($cpp_return_type, $c_return_type, $c_return_transfer, $vfunc_call);
+      $c_callback_call = 'return ' . $c_callback_call;
+      $last_return = nl () .
+                     nl ('  typedef ' . $c_return_type . ' RType;') .
+                         '  return RType();';
+    }
+    else
+    {
+      $vfunc_call = nl ($vfunc_call . ';') .
+                    nl ('        return');
+    }
+
+    my $parent_from_object = Common::Output::Shared::get_parent_from_object $wrap_parser, 'self';
+    my $c_type = Common::Output::Shared::get_c_type $wrap_parser;
+
+    $code_string = (Common::Output::Shared::ifdef $ifdef) .
+                   nl ($c_return_type . ' ' . $cpp_class_type . '::' . $c_signal_name . '_callback(' . $c_type . '* self, ' . $c_params_str . ')') .
+                   nl ('{') .
+                   nl ('  // First, do a simple cast to ObjectBase. We will have to do a dynamic cast') .
+                   nl ('  // eventually, but it is not necessary to check whether we need to call') .
+                   nl ('  // the vfunc.') .
+                   nl ('  Glib::ObjectBase* const obj_base(static_cast<Glib::ObjectBase*>(') .
+                   nl ('    Glib::ObjectBase::_get_current_wrapper(static_cast<GObject*>(self))));') .
+                   nl ('  // Non-gmmproc-generated custom classes implicitly call the default') .
+                   nl ('  // Glib::ObjectBase constructor, which sets is_derived_. But gmmproc-generated') .
+                   nl ('  // classes can use this optimisation, which avoids the unnecessary parameter') .
+                   nl ('  // parameter conversions if there is no possibility of the virtual function being') .
+                   nl ('  // overriden:') .
+                   nl ('  if (obj_base && obj_base->is_derived_())') .
+                   nl ('  {') .
+                   nl ('    // We need to do a dynamic cast to get the real object type, to call the C++') .
+                   nl ('    // vfunc on it.') .
+                   nl ('    CppObjectBase* const obj(dynamic_cast<CppObjectType* const>(obj_base));') .
+                   nl () .
+                   nl ('    if (obj) // This can be NULL during destruction.') .
+                   nl ('    {') .
+                   nl ('      try // Trap C++ exceptions which would normally be lost because this is a C callback.') .
+                   nl ('      {') .
+                   nl ('        // Call the virtual member method, which derived classes might override.') .
+                   nl ('        ' . $vfunc_call . ';')
+                   nl ('      }') .
+                   nl ('      catch (...)') .
+                   nl ('      {') .
+                   nl ('        Glib::exception_handlers_invoke();') .
+                   nl ('      }') .
+                   nl ('    }') .
+                   nl ('  }') .
+                   nl () .
+                   nl ('  BaseClassType* const base(static_cast<BaseClassType*>(' . $parent_from_object . '));') .
+                   nl () .
+                   nl ('  // Call the original underlying C function:') .
+                   nl ('  if (base && base->' . $c_signal_name . ')') .
+                   nl ('  {') .
+                   nl ('    ' . $c_callback_call . ';') .
+                   nl ('  }' ) .
+                   nl ($last_return . '}') .
+                   nl () .
+                   (Common::Output::Shared::endif $ifdef);
+
+    $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_CC_DEFAULT_SIGNAL_HANDLERS;
+    $section_manager->append_string_to_section ($code_string, $section);
+  }
+}
+
+# TODO: Add custom_signal_handler.
+sub output ($$$$$$$$$$$$$$$$)
+{
+  my ($wrap_parser, $ifdef, $c_return_type, $c_return_transfer, $c_signal_name, $c_signal_string, $c_param_types, $c_param_names, $c_param_transfers, $cpp_return_type, $cpp_signal_name, $cpp_param_types, $cpp_param_names, $custom_c_callback, $default_signal_handler_enabled) = @_;
+
+  _output_h $wrap_parser, $ifdef, $cpp_return_type, $cpp_signal_name, $cpp_param_types, $default_signal_handler_enabled;
+  _output_p_h $wrap_parser, $ifdef, $c_return_type, $c_signal_name, $c_param_types, $c_param_names, $default_signal_handler_enabled;
+  _output_cc $wrap_parser, $ifdef, $c_return_type, $c_return_transfer, $c_signal_name, $c_signal_string, $c_param_types, $c_param_names, $c_param_transfers, $cpp_return_type, $cpp_signal_name, $cpp_param_types, $custom_c_callback, $default_signal_handler_enabled;
+  _output_p_cc $wrap_parser, $ifdef, $c_return_type, $c_return_transfer, $c_signal_name, $c_param_types, $c_param_names, $c_param_transfers, $cpp_return_type, $cpp_signal_name, $cpp_param_types, $default_signal_handler_enabled;
+}
+
+1; # indicate proper module load.
diff --git a/tools/pm/Common/Output/VFunc.pm b/tools/pm/Common/Output/VFunc.pm
new file mode 100644
index 0000000..f24978a
--- /dev/null
+++ b/tools/pm/Common/Output/VFunc.pm
@@ -0,0 +1,255 @@
+# -*- mode: perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# gmmproc - Common::Output::VFunc module
+#
+# Copyright 2012 glibmm development team
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+#
+
+package Common::Output::VFunc;
+
+use strict;
+use warnings;
+
+sub nl
+{
+  return Common::Output::Shared::nl @_;
+}
+
+sub _output_h ($$$$$$$)
+{
+  my ($wrap_parser, $ifdef, $cpp_return_type, $cpp_vfunc_name, $cpp_param_types, $cpp_param_names, $const) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $main_section = $wrap_parser->get_main_section;
+  my $cpp_params_str = Common::Output::Shared::paramzipstr $cpp_param_types, $cpp_param_names;
+  my $code_string = (Common::Output::Shared::ifdef $ifdef) .
+                    (nl 'virtual ', $cpp_return_type, ' ', $cpp_vfunc_name, '(', $cpp_params_str, ($const ? ') const;' : ');')) .
+                    (nl) .
+                    Common::Output::Shared::endif $ifdef;
+
+  $section_manager->append_string_to_section ($code_string, $main_section);
+}
+
+sub _output_p_h ($$$$$$$)
+{
+  my ($wrap_parser, $ifdef, $c_return_type, $c_vfunc_name, $c_param_types, $c_param_names, $errthrow) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $c_params_str = (Common::Output::Shared::paramzipstr $c_param_types, $c_param_names) . ($errthrow ? ', GError** gerror' : '');
+  my $code_string = (Common::Output::Shared::ifdef $ifdef) .
+                    (nl '  static ', $c_return_type, ' ', $c_vfunc_name, '_vfunc_callback(', $c_params_str, ');') .
+                      (nl) .
+                      Common::Output::Shared::endif $ifdef;
+  my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_H_VFUNCS;
+
+  $section_manager->append_string_to_section ($code_string, $section);
+}
+
+sub _output_cc ($$$$$$$$$$$$$)
+{
+  my ($wrap_parser, $ifdef, $c_return_type, $c_return_transfer, $c_vfunc_name, $c_param_types, $c_param_transfers, $cpp_return_type, $cpp_vfunc_name, $cpp_param_types, $cpp_param_names, $const, $errthrow) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+  my $parent_from_object = Common::Output::Shared::get_parent_from_object $wrap_parser, 'gobject_';
+  my $cpp_params_str = Common::Output::Shared::paramzipstr $cpp_param_types, $cpp_param_names;
+  my $code_string = (Common::Output::Shared::ifdef $ifdef) .
+                    (nl $cpp_return_type, ' ', $full_cpp_type, '::', $cpp_vfunc_name, '(', $cpp_params_str, ($const ? ') const' : ')')) .
+                    (nl '{') .
+                    (nl '  BaseClassType* const base(static_cast<BaseClassType*>(' . $parent_from_object . '));') .
+                    (nl) .
+                    (nl '  if (base && base->' . $c_vfunc_name . ')') .
+                    (nl '  {');
+  my $ret_void = ($cpp_return_type eq 'void');
+  my $c_type = Common::Output::Shared::get_c_type $wrap_parser;
+  my $gobj = ($const ? 'const_cast< ' . $c_type . ' >(gobj())' : 'gobj()');
+  my $cpp_to_c_params_str = (Common::Output::Shared::convzipstr $wrap_parser, $cpp_param_types, $c_param_types, $c_param_transfers, $cpp_param_names) . ($errthrow ? ', &temp_error' : '');
+  my $c_func_invocation = join '', '(*base->', $c_vfunc_name, ')(', $gobj, ', ', $cpp_to_c_params_str . ')';
+  my $last_return = '';
+  my $conversions_store = $wrap_parser->get_conversions_store;
+  my $error_init_string = (nl '    GError* temp_error(0);');
+  my $errthrow_string = (nl '    if (temp_error)') .
+                        (nl '    {') .
+                        (nl '      ::Glib::Error::throw_exception(temp_error);') .
+                        (nl '    }');
+
+  if ($ret_void)
+  {
+    if ($errthrow)
+    {
+      $code_string += $error_init_string .
+                      (nl) .
+                      (nl '    ', $c_func_invocation, ';') .
+                      (nl) .
+                      $errthrow_string .
+                      (nl) .
+                      (nl '    return;');
+    }
+    else
+    {
+      $code_string += (nl '    ', $c_func_invocation, ';') .
+                      (nl '    return;');
+    }
+  }
+  else
+  {
+    my $conv = '';
+
+    if ($errthrow)
+    {
+      $code_string += $error_init_string .
+                      (nl '    ', $c_return_type, ' temp_retval(', $c_func_invocation, ');') .
+                      (nl) .
+                      $errthrow_string .
+                      (nl);
+      $conv = $conversions_store->get_conversion ($c_return_type, $cpp_return_type, $c_return_transfer, 'temp_retval');
+    }
+    else
+    {
+      $conv = $conversions_store->get_conversion ($c_return_type, $cpp_return_type, $c_return_transfer, $c_func_invocation);
+    }
+    $code_string += nl ('    return ' . $conv . ';');
+    $last_return = (nl) .
+                   (nl '  typedef ' . $cpp_return_type . ' RType;') .
+                   (nl '  return RType();');
+  }
+  $code_string += (nl '  }') .
+                  (nl $last_return . '}') .
+                  Common::Output::Shared::endif $ifdef;
+
+  my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_VFUNCS;
+
+  $section_manager->append_string_to_section ($code_string, $section);
+}
+
+sub _output_p_cc ($$$$$$$$$$$$)
+{
+  my ($wrap_parser, $ifdef, $c_return_type, $c_return_transfer, $c_vfunc_name, $c_param_types, $c_param_names, $c_param_transfers, $cpp_return_type, $cpp_vfunc_name, $cpp_param_types, $errthrow) = @_;
+  my $section_manager = $wrap_parser->get_section_manager;
+  my $cpp_class_type = Common::Output::Shared::get_cpp_class_type $wrap_parser;
+  my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_CC_INIT_VFUNCS;
+  my $code_string = (Common::Output::Shared::ifdef $ifdef) .
+                    (nl '  klass->' . $c_vfunc_name . ' = &' . $c_vfunc_name . '_vfunc_callback;') .
+                    (nl) .
+                    Common::Output::Shared::endif $ifdef;
+
+  $section_manager->append_string_to_section ($code_string, $section);
+
+  my $c_params_str = (Common::Output::Shared::paramzipstr $c_param_types, $c_param_names) . ($errthrow ? ', GError** gerror' : '');
+  my $ret_void = ($c_return_type eq 'void');
+  my $conversions_store = $wrap_parser->get_conversions_store;
+  my $convs_str = Common::Output::Shared::convzipstr $wrap_parser, $c_param_types, $cpp_param_types, $c_param_transfers, $c_param_names;
+  my $vfunc_call = 'obj->' . $cpp_vfunc_name . '(' . $convs_str . ')';
+  my $c_callback_call = '(*base->' . $c_vfunc_name . '(self, ' . (join ', ', @{$c_param_names}) . ($errthrow ? ', gerror' : '') . ')';
+  my $last_return = '';
+  my $after_catch_return = '';
+
+  unless ($ret_void)
+  {
+    $vfunc_call = 'return ' . $conversions_store->get_conversion ($cpp_return_type, $c_return_type, $c_return_transfer, $vfunc_call);
+    $c_callback_call = 'return ' . $c_callback_call;
+    $after_catch_return = (nl) .
+                          (nl '      typedef ', $c_return_type, ' RType;') .
+                          (nl '      return RType();');
+    $last_return = (nl) .
+                   (nl '  typedef ' . $c_return_type . ' RType;') .
+                       '  return RType();';
+  }
+  else
+  {
+    $vfunc_call = (nl $vfunc_call . ';') .
+                  (nl '        return');
+    $after_catch_return = (nl) .
+                          (nl '      return;');
+  }
+
+  my $parent_from_object = Common::Output::Shared::get_parent_from_object $wrap_parser, 'self';
+  my $c_type = Common::Output::Shared::get_c_type $wrap_parser;
+
+  $code_string = (Common::Output::Shared::ifdef $ifdef) .
+                 (nl $c_return_type, ' ', $cpp_class_type . '::' . $c_vfunc_name . '_vfunc_callback(', $c_type, '* self, ', $c_params_str, ')') .
+                 (nl '{') .
+                 (nl '  // First, do a simple cast to ObjectBase. We will have to do a dynamic cast') .
+                 (nl '  // eventually, but it is not necessary to check whether we need to call') .
+                 (nl '  // the vfunc.') .
+                 (nl '  Glib::ObjectBase* const obj_base(static_cast<Glib::ObjectBase*>(') .
+                 (nl '    Glib::ObjectBase::_get_current_wrapper(static_cast<GObject*>(self))));') .
+                 (nl '  // Non-gmmproc-generated custom classes implicitly call the default') .
+                 (nl '  // Glib::ObjectBase constructor, which sets is_derived_. But gmmproc-generated') .
+                 (nl '  // classes can use this optimisation, which avoids the unnecessary parameter') .
+                 (nl '  // parameter conversions if there is no possibility of the virtual function being') .
+                 (nl '  // overriden:') .
+                 (nl '  if (obj_base && obj_base->is_derived_())') .
+                 (nl '  {') .
+                 (nl '    // We need to do a dynamic cast to get the real object type, to call the C++') .
+                 (nl '    // vfunc on it.') .
+                 (nl '    CppObjectBase* const obj(dynamic_cast<CppObjectType* const>(obj_base));') .
+                 (nl) .
+                 (nl '    if (obj) // This can be NULL during destruction.') .
+                 (nl '    {') .
+                 (nl '      try // Trap C++ exceptions which would normally be lost because this is a C callback.') .
+                 (nl '      {') .
+                 (nl '        // Call the virtual member method, which derived classes might override.') .
+                 (nl '        ' . $vfunc_call . ';') .
+                 (nl '      }');
+
+  if ($errthrow)
+  {
+    $code_string += (nl '      catch (const Glib::Error& error)') .
+                    (nl '      {') .
+                    (nl '        error.propagate(gerror);') .
+                    (nl '      }');
+  }
+
+  $code_string += (nl '      catch (...)') .
+                  (nl '      {') .
+                  (nl '        Glib::exception_handlers_invoke();') .
+                  (nl '      }') .
+                  $after_catch_return .
+                  (nl '    }') .
+                  (nl '  }') .
+                  (nl) .
+                  (nl '  BaseClassType* const base(static_cast<BaseClassType*>(' . $parent_from_object . '));') .
+                  (nl) .
+                  (nl '  // Call the original underlying C function:') .
+                  (nl '  if (base && base->' . $c_vfunc_name . ')') .
+                  (nl '  {') .
+                  (nl '    ' . $c_callback_call . ';') .
+                  (nl '  }' ) .
+                  (nl $last_return . '}') .
+                  (nl) .
+                  (Common::Output::Shared::endif $ifdef);
+
+  $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_CC_VFUNCS;
+  $section_manager->append_string_to_section ($code_string, $section);
+}
+
+sub output ($$$$$$$$$$$$$$$$)
+{
+  my ($wrap_parser, $ifdef, $c_return_type, $c_return_transfer, $c_vfunc_name, $c_param_types, $c_param_names, $c_param_transfers, $cpp_return_type, $cpp_vfunc_name, $cpp_param_types, $cpp_param_names, $const, $custom_vfunc, $custom_vfunc_callback, $errthrow) = @_;
+
+  _output_h $wrap_parser, $ifdef, $cpp_return_type, $cpp_vfunc_name, $cpp_param_types, $cpp_param_names, $const;
+  _output_p_h $wrap_parser, $ifdef, $c_return_type, $c_vfunc_name, $c_param_types, $c_param_names, $errthrow;
+
+  unless ($custom_vfunc)
+  {
+    _output_cc $wrap_parser, $ifdef, $c_return_type, $c_return_transfer, $c_vfunc_name, $c_param_types, $c_param_transfers, $cpp_return_type, $cpp_vfunc_name, $cpp_param_types, $cpp_param_names, $const, $errthrow;
+  }
+
+  unless ($custom_vfunc_callback)
+  {
+    _output_p_cc $wrap_parser, $ifdef, $c_return_type, $c_return_transfer, $c_vfunc_name, $c_param_types, $c_param_names, $c_param_transfers, $cpp_return_type, $cpp_vfunc_name, $cpp_param_types, $errthrow;
+  }
+}
+
+1; # indicate proper module load.



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]