diff --git a/giscanner/annotationparser.py b/giscanner/annotationparser.py
index 003ff2c..3c9d737 100644
--- a/giscanner/annotationparser.py
+++ b/giscanner/annotationparser.py
@@ -43,6 +43,7 @@ TAG_SINCE = 'since'
 TAG_DEPRECATED = 'deprecated'
 TAG_RETURNS = 'returns'
 TAG_RETURNS_ALT = 'return value'
+TAG_ANNOTATIONS = 'annotations'
 
 # Options - annotations for parameters and return values
 OPT_ALLOW_NONE = 'allow-none'
@@ -92,7 +93,7 @@ class DocTag(object):
 
     def __init__(self, name):
         self.name = name
-        self.options = []
+        self.options = {}
         self.comment = None
 
 
@@ -178,23 +179,30 @@ class AnnotationParser(object):
             elif not ': ' in line:
                 comment_lines.append(line)
                 continue
-            tag = self._parse_tag(line)
-            block.tags[tag.name.lower()] = tag
+            tag_name, value = self._split_tag_namevalue(line)
+            canon_name = tag_name.lower()
+            if canon_name in block.tags:
+                print >>sys.stderr, "Multiple definition of tag %r" % (canon_name, )
+            block.tags[canon_name] = self._create_tag(canon_name, value)
         block.comment = '\n'.join(comment_lines)
         self._blocks[block.name] = block
-
-    def _parse_tag(self, raw):
-        # Tag: bar
-        # Tag: bar opt1 opt2
+        
+    def _split_tag_namevalue(self, raw):
+        """Split a line into tag name and value"""
         parts = raw.split(': ', 1)
         if len(parts) == 1:
             tag_name = parts[0]
             value = ''
         else:
             tag_name, value = parts
-        options, rest = self._parse_options(value)
+        return (tag_name, value)        
+
+    def _create_tag(self, tag_name, value):
+        # Tag: bar
+        # Tag: bar opt1 opt2
         tag = DocTag(tag_name)
-        tag.value = value
+        tag.value = value        
+        options, rest = self._parse_options(tag.value)
         tag.options = options
         tag.comment = rest
         return tag
@@ -271,7 +279,7 @@ class AnnotationApplier(object):
 
     def _parse_class(self, class_):
         block = self._blocks.get(class_.type_name)
-        self._parse_version(class_, block)
+        self._parse_node_common(class_, block)
         self._parse_constructors(class_.constructors)
         self._parse_methods(class_.methods)
         self._parse_methods(class_.static_methods)
@@ -283,7 +291,7 @@ class AnnotationApplier(object):
 
     def _parse_interface(self, interface):
         block = self._blocks.get(interface.type_name)
-        self._parse_version(interface, block)
+        self._parse_node_common(interface, block)
         self._parse_methods(interface.methods)
         self._parse_properties(interface, interface.properties)
         self._parse_signals(interface, interface.signals)
@@ -293,7 +301,7 @@ class AnnotationApplier(object):
 
     def _parse_record(self, record):
         block = self._blocks.get(record.symbol)
-        self._parse_version(record, block)
+        self._parse_node_common(record, block)
         self._parse_constructors(record.constructors)
         self._parse_methods(record.methods)
         self._parse_fields(record, record.fields)
@@ -302,7 +310,7 @@ class AnnotationApplier(object):
 
     def _parse_boxed(self, boxed):
         block = self._blocks.get(boxed.name)
-        self._parse_version(boxed, block)
+        self._parse_node_common(boxed, block)
         self._parse_constructors(boxed.constructors)
         self._parse_methods(boxed.methods)
         if block:
@@ -310,6 +318,7 @@ class AnnotationApplier(object):
 
     def _parse_union(self, union):
         block = self._blocks.get(union.name)
+        self._parse_node_common(union, block)
         self._parse_fields(union, union.fields)
         self._parse_constructors(union.constructors)
         self._parse_methods(union.methods)
@@ -318,13 +327,13 @@ class AnnotationApplier(object):
 
     def _parse_enum(self, enum):
         block = self._blocks.get(enum.symbol)
-        self._parse_version(enum, block)
+        self._parse_node_common(enum, block)
         if block:
             enum.doc = block.comment
 
     def _parse_bitfield(self, bitfield):
         block = self._blocks.get(bitfield.symbol)
-        self._parse_version(bitfield, block)
+        self._parse_node_common(bitfield, block)
         if block:
             bitfield.doc = block.comment
 
@@ -350,14 +359,13 @@ class AnnotationApplier(object):
 
     def _parse_property(self, parent, prop):
         block = self._blocks.get('%s:%s' % (parent.type_name, prop.name))
-        self._parse_version(prop, block)
-        self._parse_deprecated(prop, block)
+        self._parse_node_common(prop, block)
         if block:
             prop.doc = block.comment
 
     def _parse_callback(self, callback):
         block = self._blocks.get(callback.ctype)
-        self._parse_version(callback, block)
+        self._parse_node_common(callback, block)        
         self._parse_params(callback, callback.parameters, block)
         self._parse_return(callback, callback.retval, block)
         if block:
@@ -365,8 +373,7 @@ class AnnotationApplier(object):
 
     def _parse_function(self, func):
         block = self._blocks.get(func.symbol)
-        self._parse_version(func, block)
-        self._parse_deprecated(func, block)
+        self._parse_node_common(func, block)
         self._parse_params(func, func.parameters, block)
         self._parse_return(func, func.retval, block)
         if block:
@@ -374,7 +381,7 @@ class AnnotationApplier(object):
 
     def _parse_signal(self, parent, signal):
         block = self._blocks.get('%s::%s' % (parent.type_name, signal.name))
-        self._parse_version(signal, block)
+        self._parse_node_common(signal, block)
         self._parse_deprecated(signal, block)
         # We're only attempting to name the signal parameters if
         # the number of parameter tags (@foo) is the same or greater
@@ -552,6 +559,11 @@ class AnnotationApplier(object):
                     "none, container, full." % (node, parent.name, transfer))
         return transfer
 
+    def _parse_node_common(self, node, block):
+        self._parse_version(node, block)
+        self._parse_deprecated(node, block)
+        self._parse_annotations(node, block)
+
     def _parse_version(self, node, block):
         since_tag = self._get_tag(block, TAG_SINCE)
         if since_tag is None:
@@ -572,6 +584,13 @@ class AnnotationApplier(object):
         if version is not None:
             node.deprecated_version = version
 
+    def _parse_annotations(self, node, block):
+        annos_tag = self._get_tag(block, TAG_ANNOTATIONS)
+        if annos_tag is None:
+            return
+        for key,value in annos_tag.options.iteritems():
+            node.annotations.append((key, value.one()))
+
     def _guess_direction(self, node):
         if node.direction:
             return node.direction
diff --git a/giscanner/ast.py b/giscanner/ast.py
index ff65312..d1276f2 100644
--- a/giscanner/ast.py
+++ b/giscanner/ast.py
@@ -146,6 +146,7 @@ class Node(object):
 
     def __init__(self, name=None):
         self.name = name
+        self.annotations = [] # (key, value)*
         self.deprecated = None
         self.deprecated_version = None
         self.version = None
diff --git a/giscanner/girwriter.py b/giscanner/girwriter.py
index 116681a..a81784e 100644
--- a/giscanner/girwriter.py
+++ b/giscanner/girwriter.py
@@ -127,6 +127,11 @@ and/or use gtk-doc annotations. ''')
         if node.version:
             attrs.append(('version', node.version))
 
+    def _write_annotations(self, node):
+        for key,value in node.annotations:
+            self.write_tag('annotation', ('name', key),
+                           value)
+
     def _append_deprecated(self, node, attrs):
         if node.deprecated:
             attrs.append(('deprecated', node.deprecated))
@@ -153,6 +158,7 @@ and/or use gtk-doc annotations. ''')
         self._append_deprecated(func, attrs)
         self._append_throws(func, attrs)
         with self.tagcontext(tag_name, attrs):
+            self._write_annotations(func)
             self._write_return_type(func.retval)
             self._write_parameters(func.parameters)
 
@@ -270,6 +276,7 @@ and/or use gtk-doc annotations. ''')
             attrs.append(('c:type', enum.symbol))
 
         with self.tagcontext('enumeration', attrs):
+            self._write_annotations(enum)        
             for member in enum.members:
                 self._write_member(member)
 
@@ -286,6 +293,7 @@ and/or use gtk-doc annotations. ''')
         else:
             attrs.append(('c:type', bitfield.symbol))
         with self.tagcontext('bitfield', attrs):
+            self._write_annotations(bitfield)
             for member in bitfield.members:
                 self._write_member(member)
 
@@ -326,6 +334,7 @@ and/or use gtk-doc annotations. ''')
             if node.class_struct:
                 attrs.append(('glib:class-struct', node.class_struct.name))
         with self.tagcontext(tag_name, attrs):
+            self._write_annotations(node)
             if isinstance(node, GLibObject):
                 for iface in node.interfaces:
                     self.write_tag('implements', [('name', iface)])
@@ -353,6 +362,7 @@ and/or use gtk-doc annotations. ''')
             attrs.append(('doc', boxed.doc))
         attrs.extend(self._boxed_attrs(boxed))
         with self.tagcontext('glib:boxed', attrs):
+            self._write_annotations(boxed)            
             for method in boxed.constructors:
                 self._write_constructor(method)
             for method in boxed.methods:
@@ -374,6 +384,7 @@ and/or use gtk-doc annotations. ''')
         if prop.doc:
             attrs.append(('doc', prop.doc))
         with self.tagcontext('property', attrs):
+            self._write_annotations(prop)
             self._write_type(prop.type)
 
     def _write_callback(self, callback):
@@ -385,6 +396,7 @@ and/or use gtk-doc annotations. ''')
         self._append_deprecated(callback, attrs)
         self._append_throws(callback, attrs)
         with self.tagcontext('callback', attrs):
+            self._write_annotations(callback)
             self._write_return_type(callback.retval)
             self._write_parameters(callback.parameters)
 
@@ -410,6 +422,7 @@ and/or use gtk-doc annotations. ''')
         if isinstance(record, GLibBoxed):
             attrs.extend(self._boxed_attrs(record))
         with self.tagcontext('record', attrs):
+            self._write_annotations(record)
             if record.fields:
                 for field in record.fields:
                     self._write_field(field)
@@ -431,6 +444,7 @@ and/or use gtk-doc annotations. ''')
         if isinstance(union, GLibBoxed):
             attrs.extend(self._boxed_attrs(union))
         with self.tagcontext('union', attrs):
+            self._write_annotations(union)
             if union.fields:
                 for field in union.fields:
                     self._write_field(field)
@@ -461,6 +475,7 @@ and/or use gtk-doc annotations. ''')
             if field.bits:
                 attrs.append(('bits', str(field.bits)))
             with self.tagcontext('field', attrs):
+                self._write_annotations(field)
                 self._write_type(field.type)
 
     def _write_signal(self, signal):
@@ -470,5 +485,6 @@ and/or use gtk-doc annotations. ''')
         self._append_version(signal, attrs)
         self._append_deprecated(signal, attrs)
         with self.tagcontext('glib:signal', attrs):
+            self._write_annotations(signal)
             self._write_return_type(signal.retval)
             self._write_parameters(signal.parameters)
diff --git a/tests/scanner/annotation.c b/tests/scanner/annotation.c
index 20c2729..e457fab 100644
--- a/tests/scanner/annotation.c
+++ b/tests/scanner/annotation.c
@@ -565,5 +565,15 @@ annotation_versioned (void)
 {
 }
 
+/**
+ * annotation_object_extra_annos:
+ * 
+ * Annotations: (org.foobar testvalue)
+ */
+void
+annotation_object_extra_annos (AnnotationObject *object)
+{
+  
+}
 
 char backslash_parsing_tester_2 = '\\';
diff --git a/tests/scanner/annotation.h b/tests/scanner/annotation.h
index 6904f15..7ee58bd 100644
--- a/tests/scanner/annotation.h
+++ b/tests/scanner/annotation.h
@@ -111,6 +111,8 @@ void     annotation_versioned           (void);
 char **  annotation_string_zero_terminated (void);
 void     annotation_string_zero_terminated_out (char ***out);
 
+void     annotation_object_extra_annos (AnnotationObject *object);
+
 /**
  * AnnotationStruct:
  *
