--- Modules/NaturalDocs/Languages/C.pm	2008-05-06 02:08:58.000000000 +0200
+++ Modules/NaturalDocs/Languages/C.pm	2008-06-11 16:58:10.000000000 +0200
+   ###############################################################################
+   #
+   #   Class: NaturalDocs::Languages::C
+   #
+   ###############################################################################
+   #
+   #   A subclass to handle the language variations of C#.
+   #
+   #
+   #   Topic: Language Support
+   #
+   #       Supported:
+   #
+   #       - Classes
+   #       - Namespaces (no topic generated)
+   #       - Functions
+   #       - Constructors and Destructors
+   #       - Properties
+   #       - Indexers
+   #       - Operators
+   #       - Delegates
+   #       - Variables
+   #       - Constants
+   #       - Events
+   #       - Enums
+   #
+   #       Not supported yet:
+   #
+   #       - Autodocumenting enum members
+   #       - Using alias
+   #
+   ###############################################################################
+   
+   # This file is part of Natural Docs, which is Copyright (C) 2003-2008 Greg Valure
+   # Natural Docs is licensed under the GPL
+   
+   use strict;
+   use integer;
+   
+   package NaturalDocs::Languages::C;
+   
+   use base 'NaturalDocs::Languages::Advanced';
+   
+   
+   
+   
+   ###############################################################################
+   # Group: Package Variables
+   
+   #
+   #   hash: classKeywords
+   #   An existence hash of all the acceptable class keywords.  The keys are in all lowercase.
+   #
+   my %classKeywords = ( 'class' => 1,
+                                       'struct' => 1,
+                                       'interface' => 1 );
+   
+   #
+   #   hash: classModifiers
+   #   An existence hash of all the acceptable class modifiers.  The keys are in all lowercase.
+   #
+   my %classModifiers = ( 'new' => 1,
+                                      'public' => 1,
+                                      'protected' => 1,
+                                      'internal' => 1,
+                                      'private' => 1,
+                                      'abstract' => 1,
+                                      'sealed' => 1,
+                                      'unsafe' => 1,
+   		                   'static' => 1,
+                                      'typedef' => 1);
+   
+   #
+   #   hash: functionModifiers
+   #   An existence hash of all the acceptable function modifiers.  Also applies to properties.  Also encompasses those for operators
+   #   and indexers, but have more than are valid for them.  The keys are in all lowercase.
+   #
+   my %functionModifiers = ( 'new' => 1,
+                                          'public' => 1,
+                                          'protected' => 1,
+                                          'internal' => 1,
+                                          'private' => 1,
+                                          'static' => 1,
+                                          'virtual' => 1,
+                                          'sealed' => 1,
+                                          'override' => 1,
+                                          'abstract' => 1,
+                                          'extern' => 1,
+                                          'unsafe' => 1 );
+   
+   
+   #
+   #   hash: variableModifiers
+   #   An existence hash of all the acceptable variable modifiers.  The keys are in all lowercase.
+   #
+   my %variableModifiers = ( 'new' => 1,
+                                          'public' => 1,
+                                          'protected' => 1,
+                                          'internal' => 1,
+                                          'private' => 1,
+                                          'static' => 1,
+                                          'readonly' => 1,
+                                          'volatile' => 1,
+                                          'unsafe' => 1 );
+   
+   #
+   #   hash: enumTypes
+   #   An existence hash of all the possible enum types.  The keys are in all lowercase.
+   #
+   my %enumTypes = ( 'sbyte' => 1,
+                                'byte' => 1,
+                                'short' => 1,
+                                'ushort' => 1,
+                                'int' => 1,
+                                'uint' => 1,
+                                'long' => 1,
+                                'ulong' => 1 );
+   
+   #
+   #   hash: impossibleTypeWords
+   #   An existence hash of all the reserved words that cannot be in a type.  This includes 'enum' and all modifiers.  The keys are in
+   #   all lowercase.
+   #
+   my %impossibleTypeWords = ( 'abstract' => 1, 'as' => 1, 'base' => 1, 'break' => 1, 'case' => 1, 'catch' => 1,
+                                                 'checked' => 1, 'class' => 1, 'const' => 1, 'continue' => 1, 'default' => 1, 'delegate' => 1,
+                                                 'do' => 1, 'else' => 1, 'enum' => 1, 'event' => 1, 'explicit' => 1, 'extern' => 1,
+                                                 'false' => 1, 'finally' => 1, 'fixed' => 1, 'for' => 1, 'foreach' => 1, 'goto' => 1, 'if' => 1,
+                                                 'implicit' => 1, 'in' => 1, 'interface' => 1, 'internal' => 1, 'is' => 1, 'lock' => 1,
+                                                 'namespace' => 1, 'new' => 1, 'null' => 1, 'operator' => 1, 'out' => 1, 'override' => 1,
+                                                 'params' => 1, 'private' => 1, 'protected' => 1, 'public' => 1, 'readonly' => 1, 'ref' => 1,
+                                                 'return' => 1, 'sealed' => 1, 'sizeof' => 1, 'stackalloc' => 1, 'static' => 1,
+                                                 'struct' => 1, 'switch' => 1, 'this' => 1, 'throw' => 1, 'true' => 1, 'try' => 1, 'typeof' => 1,
+                                                 'unchecked' => 1, 'unsafe' => 1, 'using' => 1, 'virtual' => 1, 'volatile' => 1, 'while' => 1 );
+   # Deleted from the list: object, string, bool, decimal, sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, void
+   
+   
+   
+   ###############################################################################
+   # Group: Interface Functions
+   
+   
+   #
+   #   Function: PackageSeparator
+   #   Returns the package separator symbol.
+   #
+   sub PackageSeparator
+       {  return '.';  };
+   
+   
+   #
+   #   Function: EnumValues
+   #   Returns the <EnumValuesType> that describes how the language handles enums.
+   #
+   sub EnumValues
+       {  return ::ENUM_UNDER_TYPE();  };
+   
+   
+   #
+   #   Function: ParseFile
+   #
+   #   Parses the passed source file, sending comments acceptable for documentation to <NaturalDocs::Parser->OnComment()>.
+   #
+   #   Parameters:
+   #
+   #       sourceFile - The <FileName> to parse.
+   #       topicList - A reference to the list of <NaturalDocs::Parser::ParsedTopics> being built by the file.
+   #
+   #   Returns:
+   #
+   #       The array ( autoTopics, scopeRecord ).
+   #
+   #       autoTopics - An arrayref of automatically generated topics from the file, or undef if none.
+   #       scopeRecord - An arrayref of <NaturalDocs::Languages::Advanced::ScopeChanges>, or undef if none.
+   #
+   sub ParseFile #(sourceFile, topicsList)
+       {
+       my ($self, $sourceFile, $topicsList) = @_;
+   
+       $self->ParseForCommentsAndTokens($sourceFile, [ '//' ], [ '/*', '*/' ], [ '///' ], [ '/**', '*/' ] );
+   
+       my $tokens = $self->Tokens();
+       my $index = 0;
+       my $lineNumber = 1;
+   
+       while ($index < scalar @$tokens)
+           {
+           if ($self->TryToSkipWhitespace(\$index, \$lineNumber) ||
+               $self->TryToGetNamespace(\$index, \$lineNumber) ||
+               $self->TryToGetUsing(\$index, \$lineNumber) ||
+               $self->TryToGetClass(\$index, \$lineNumber) ||
+               $self->TryToGetFunction(\$index, \$lineNumber) ||
+               $self->TryToGetOverloadedOperator(\$index, \$lineNumber) ||
+               $self->TryToGetVariable(\$index, \$lineNumber) ||
+               $self->TryToGetEnum(\$index, \$lineNumber) )
+               {
+               # The functions above will handle everything.
+               }
+   
+           elsif ($tokens->[$index] eq '{')
+               {
+               $self->StartScope('}', $lineNumber, undef, undef, undef);
+               $index++;
+               }
+   
+           elsif ($tokens->[$index] eq '}')
+               {
+               if ($self->ClosingScopeSymbol() eq '}')
+                   {  $self->EndScope($lineNumber);  };
+   
+               $index++;
+               }
+   
+           else
+               {
+               $self->SkipRestOfStatement(\$index, \$lineNumber);
+               };
+           };
+   
+   
+       # Don't need to keep these around.
+       $self->ClearTokens();
+   
+   
+       my $autoTopics = $self->AutoTopics();
+   
+       my $scopeRecord = $self->ScopeRecord();
+       if (defined $scopeRecord && !scalar @$scopeRecord)
+           {  $scopeRecord = undef;  };
+   
+       return ( $autoTopics, $scopeRecord );
+       };
+   
+   
+   
+   ###############################################################################
+   # Group: Statement Parsing Functions
+   # All functions here assume that the current position is at the beginning of a statement.
+   #
+   # Note for developers: I am well aware that the code in these functions do not check if we're past the end of the tokens as
+   # often as it should.  We're making use of the fact that Perl will always return undef in these cases to keep the code simpler.
+   
+   
+   #
+   #   Function: TryToGetNamespace
+   #
+   #   Determines whether the position is at a namespace declaration statement, and if so, adjusts the scope, skips it, and returns
+   #   true.
+   #
+   #   Why no topic?:
+   #
+   #       The main reason we don't create a Natural Docs topic for a namespace is because in order to declare class A.B.C in C#,
+   #       you must do this:
+   #
+   #       > namespace A.B
+   #       >    {
+   #       >    class C
+   #       >        { ... }
+   #       >    }
+   #
+   #       That would result in a namespace topic whose only purpose is really to qualify C.  It would take the default page title, and
+   #       thus the default menu title.  So if you have files for A.B.X, A.B.Y, and A.B.Z, they all will appear as A.B on the menu.
+   #
+   #       If something actually appears in the namespace besides a class, it will be handled by
+   #       <NaturalDocs::Parser->AddPackageDelineators()>.  That function will add a package topic to correct the scope.
+   #
+   #       If the user actually documented it, it will still appear because of the manual topic.
+   #
+   sub TryToGetNamespace #(indexRef, lineNumberRef)
+       {
+       my ($self, $indexRef, $lineNumberRef) = @_;
+       my $tokens = $self->Tokens();
+   
+       if (lc($tokens->[$$indexRef]) ne 'namespace')
+           {  return undef;  };
+   
+       my $index = $$indexRef + 1;
+       my $lineNumber = $$lineNumberRef;
+   
+       if (!$self->TryToSkipWhitespace(\$index, \$lineNumber))
+           {  return undef;  };
+   
+       my $name;
+   
+       while ($tokens->[$index] =~ /^[a-z_\.\@]/i)
+           {
+           $name .= $tokens->[$index];
+           $index++;
+           };
+   
+       if (!defined $name)
+           {  return undef;  };
+   
+       $self->TryToSkipWhitespace(\$index, \$lineNumber);
+   
+       if ($tokens->[$index] ne '{')
+           {  return undef;  };
+   
+       $index++;
+   
+   
+       # We found a valid one if we made it this far.
+   
+       my $autoTopic = NaturalDocs::Parser::ParsedTopic->New(::TOPIC_CLASS(), $name,
+                                                                                            $self->CurrentScope(), $self->CurrentUsing(),
+                                                                                            undef,
+                                                                                            undef, undef, $$lineNumberRef);
+   
+       # We don't add an auto-topic for namespaces.  See the function documentation above.
+   
+       NaturalDocs::Parser->OnClass($autoTopic->Package());
+   
+       $self->StartScope('}', $lineNumber, $autoTopic->Package());
+   
+       $$indexRef = $index;
+       $$lineNumberRef = $lineNumber;
+   
+       return 1;
+       };
+   
+   
+   #
+   #   Function: TryToGetClass
+   #
+   #   Determines whether the position is at a class declaration statement, and if so, generates a topic for it, skips it, and
+   #   returns true.
+   #
+   #   Supported Syntaxes:
+   #
+   #       - Classes
+   #       - Structs
+   #       - Interfaces
+   #
+   sub TryToGetClass #(indexRef, lineNumberRef)
+       {
+       my ($self, $indexRef, $lineNumberRef) = @_;
+       my $tokens = $self->Tokens();
+   
+       my $index = $$indexRef;
+       my $lineNumber = $$lineNumberRef;
+   
+       my $startIndex = $index;
+       my $startLine = $lineNumber;
+       my $needsPrototype = 0;
+   
+       if ($self->TryToSkipAttributes(\$index, \$lineNumber))
+           {  $self->TryToSkipWhitespace(\$index, \$lineNumber);  }
+   
+       my @modifiers;
+   
+       while ($tokens->[$index] =~ /^[a-z]/i &&
+                 !exists $classKeywords{lc($tokens->[$index])} &&
+                 exists $classModifiers{lc($tokens->[$index])} )
+           {
+           push @modifiers, lc($tokens->[$index]);
+           $index++;
+   
+           $self->TryToSkipWhitespace(\$index, \$lineNumber);
+           };
+   
+       if (!exists $classKeywords{lc($tokens->[$index])})
+           {  return undef;  };
+   
+       my $lcClassKeyword = lc($tokens->[$index]);
+   
+       $index++;
+   
+       if (!$self->TryToSkipWhitespace(\$index, \$lineNumber))
+           {  return undef;  };
+   
+       my $name;
+   
+       while ($tokens->[$index] =~ /^[a-z_\@]/i)
+           {
+           $name .= $tokens->[$index];
+           $index++;
+           };
+   
+       if (!defined $name)
+           {  return undef;  };
+   
+       $self->TryToSkipWhitespace(\$index, \$lineNumber);
+   
+       if ($tokens->[$index] eq '<')
+       	{
+       	# XXX: This is half-assed.
+       	$index++;
+       	$needsPrototype = 1;
+   
+       	while ($index < scalar @$tokens && $tokens->[$index] ne '>')
+       		{
+       		$index++;
+       		}
+   
+       	if ($index < scalar @$tokens)
+       		{
+       		$index++;
+       		}
+       	else
+       		{  return undef;  }
+   
+           $self->TryToSkipWhitespace(\$index, \$lineNumber);
+       	}
+   
+       my @parents;
+   
+       if ($tokens->[$index] eq ':')
+           {
+           do
+               {
+               $index++;
+   
+               $self->TryToSkipWhitespace(\$index, \$lineNumber);
+   
+               my $parentName;
+   
+               while ($tokens->[$index] =~ /^[a-z_\.\@]/i)
+                   {
+                   $parentName .= $tokens->[$index];
+                   $index++;
+                   };
+   
+   	        if ($tokens->[$index] eq '<')
+   	            {
+   	            # XXX: This is still half-assed.
+   	            $index++;
+   	            $needsPrototype = 1;
+   
+   	            while ($index < scalar @$tokens && $tokens->[$index] ne '>')
+   	                {
+   	                $index++;
+   	                }
+   
+   	            if ($index < scalar @$tokens)
+   	                {
+   	                $index++;
+   	                }
+   	            else
+   	                {  return undef;  }
+   
+   	            $self->TryToSkipWhitespace(\$index, \$lineNumber);
+   	            }
+   
+               if (!defined $parentName)
+                   {  return undef;  };
+   
+               push @parents, NaturalDocs::SymbolString->FromText($parentName);
+   
+               $self->TryToSkipWhitespace(\$index, \$lineNumber);
+               }
+           while ($tokens->[$index] eq ',')
+           };
+   
+       if (lc($tokens->[$index]) eq 'where')
+       	{
+       	# XXX: This is also half-assed
+       	$index++;
+   
+       	while ($index < scalar @$tokens && $tokens->[$index] ne '{')
+       		{
+       		$index++;
+       		}
+       	}
+   
+       if ($tokens->[$index] ne '{')
+           {  return undef;  };
+   
+   
+       # If we made it this far, we have a valid class declaration.
+   
+       my @scopeIdentifiers = NaturalDocs::SymbolString->IdentifiersOf($self->CurrentScope());
+       $name = join('.', @scopeIdentifiers, $name);
+   
+       my $topicType;
+   
+       if ($lcClassKeyword eq 'interface')
+           {  $topicType = ::TOPIC_INTERFACE();  }
+       else
+           {  $topicType = ::TOPIC_CLASS();  };
+   
+       my $prototype;
+   
+       if ($needsPrototype)
+       	{
+       	$prototype = $self->CreateString($startIndex, $index);
+       	}
+   
+       my $autoTopic = NaturalDocs::Parser::ParsedTopic->New($topicType, $name,
+                                                                                            undef, $self->CurrentUsing(),
+                                                                                            $prototype,
+                                                                                            undef, undef, $$lineNumberRef);
+   
+       $self->AddAutoTopic($autoTopic);
+       NaturalDocs::Parser->OnClass($autoTopic->Package());
+   
+       foreach my $parent (@parents)
+           {
+           NaturalDocs::Parser->OnClassParent($autoTopic->Package(), $parent, $self->CurrentScope(), undef,
+                                                                  ::RESOLVE_RELATIVE());
+           };
+   
+       $self->StartScope('}', $lineNumber, $autoTopic->Package());
+   
+       $index++;
+   
+       $$indexRef = $index;
+       $$lineNumberRef = $lineNumber;
+   
+       return 1;
+       };
+   
+   
+   #
+   #   Function: TryToGetUsing
+   #
+   #   Determines whether the position is at a using statement, and if so, adds it to the current scope, skips it, and returns
+   #	true.
+   #
+   #	Supported:
+   #
+   #       - Using
+   #
+   #	Unsupported:
+   #
+   #		- Using with alias
+   #
+   sub TryToGetUsing #(indexRef, lineNumberRef)
+       {
+       my ($self, $indexRef, $lineNumberRef) = @_;
+       my $tokens = $self->Tokens();
+   
+       my $index = $$indexRef;
+       my $lineNumber = $$lineNumberRef;
+   
+       if (lc($tokens->[$index]) ne 'using')
+           {  return undef;  };
+   
+       $index++;
+       $self->TryToSkipWhitespace(\$index, \$lineNumber);
+   
+       my $name;
+   
+       while ($tokens->[$index] =~ /^[a-z_\@\.]/i)
+           {
+           $name .= $tokens->[$index];
+           $index++;
+           };
+   
+       if ($tokens->[$index] ne ';' ||
+   		!defined $name)
+           {  return undef;  };
+   
+       $index++;
+   
+   
+       $self->AddUsing( NaturalDocs::SymbolString->FromText($name) );
+   
+       $$indexRef = $index;
+       $$lineNumberRef = $lineNumber;
+   
+       return 1;
+       };
+   
+   
+   
+   #
+   #   Function: TryToGetFunction
+   #
+   #   Determines if the position is on a function declaration, and if so, generates a topic for it, skips it, and returns true.
+   #
+   #   Supported Syntaxes:
+   #
+   #       - Functions
+   #       - Constructors
+   #       - Destructors
+   #       - Properties
+   #       - Indexers
+   #       - Delegates
+   #       - Events
+   #
+   sub TryToGetFunction #(indexRef, lineNumberRef)
+       {
+       my ($self, $indexRef, $lineNumberRef) = @_;
+       my $tokens = $self->Tokens();
+   
+       my $index = $$indexRef;
+       my $lineNumber = $$lineNumberRef;
+   
+       if ($self->TryToSkipAttributes(\$index, \$lineNumber))
+           {  $self->TryToSkipWhitespace(\$index, \$lineNumber);  };
+   
+       my $startIndex = $index;
+       my $startLine = $lineNumber;
+   
+       my @modifiers;
+   
+       while ($tokens->[$index] =~ /^[a-z]/i &&
+                 exists $functionModifiers{lc($tokens->[$index])} )
+           {
+           push @modifiers, lc($tokens->[$index]);
+           $index++;
+   
+           $self->TryToSkipWhitespace(\$index, \$lineNumber);
+           };
+   
+       my $isDelegate;
+       my $isEvent;
+   
+       if (lc($tokens->[$index]) eq 'delegate')
+           {
+           $isDelegate = 1;
+           $index++;
+           $self->TryToSkipWhitespace(\$index, \$lineNumber);
+           }
+       elsif (lc($tokens->[$index]) eq 'event')
+           {
+           $isEvent = 1;
+           $index++;
+           $self->TryToSkipWhitespace(\$index, \$lineNumber);
+           };
+   
+       my $returnType = $self->TryToGetType(\$index, \$lineNumber);
+   
+       $self->TryToSkipWhitespace(\$index, \$lineNumber);
+   
+       my $name;
+       my $lastNameWord;
+   
+       while ($tokens->[$index] =~ /^[a-z\_\@\.\~\<]/i)
+           {
+           $name .= $tokens->[$index];
+   	if ($name =~ /API_CALL/)
+   	{
+   	    $index ++;
+   	    $name .= $tokens->[$index];
+   	    $index ++;
+   	    $name .= $tokens->[$index];
+   	    $index ++;
+   	    $name .= $tokens->[$index];
+   	}
+           # Ugly hack, but what else is new?  For explicit generic interface definitions, such as:
+           # IDObjectType System.Collections.Generic.IEnumerator<IDObjectType>.Current
+   
+           if ($tokens->[$index] eq '<')
+           	{
+           	do
+           		{
+   	        	$index++;
+           		$name .= $tokens->[$index];
+           		}
+           	while ($index < @$tokens && $tokens->[$index] ne '>');
+           	}
+   
+           $lastNameWord = $tokens->[$index];
+           $index++;
+           };
+   
+       if (!defined $name)
+           {
+           # Constructors and destructors don't have return types.  It's possible their names were mistaken for the return type.
+           if (defined $returnType)
+               {
+               $name = $returnType;
+               $returnType = undef;
+   
+               $name =~ /([a-z0-9_]+)$/i;
+               $lastNameWord = $1;
+               }
+           else
+               {  return undef;  };
+           };
+   
+       # If there's no return type, make sure it's a constructor or destructor.
+       if (!defined $returnType)
+           {
+           my @identifiers = NaturalDocs::SymbolString->IdentifiersOf( $self->CurrentScope() );
+   
+           if ($lastNameWord ne $identifiers[-1])
+               {  return undef;  };
+           };
+   
+       $self->TryToSkipWhitespace(\$index, \$lineNumber);
+   
+   
+       # Skip the brackets on indexers.
+       if ($tokens->[$index] eq '[' && lc($lastNameWord) eq 'this')
+           {
+           # This should jump the brackets completely.
+           $self->GenericSkip(\$index, \$lineNumber);
+           $self->TryToSkipWhitespace(\$index, \$lineNumber);
+   
+           $name .= '[]';
+           };
+   
+   
+       # Properties, indexers, events with braces
+   
+       if ($tokens->[$index] eq '{')
+           {
+           my $prototype = $self->CreateString($startIndex, $index);
+   
+           $index++;
+           $self->TryToSkipWhitespace(\$index, \$lineNumber);
+   
+           my ($aWord, $bWord, $hasA, $hasB);
+   
+           if ($isEvent)
+               {
+               $aWord = 'add';
+               $bWord = 'remove';
+               }
+           else
+               {
+               $aWord = 'get';
+               $bWord = 'set';
+               };
+   
+           while ($index < scalar @$tokens)
+               {
+               if ($self->TryToSkipAttributes(\$index, \$lineNumber))
+                   {  $self->TryToSkipWhitespace(\$index, \$lineNumber);  };
+   
+               if (lc($tokens->[$index]) eq $aWord)
+                   {  $hasA = 1;  }
+               elsif (lc($tokens->[$index]) eq $bWord)
+                   {  $hasB = 1;  }
+               elsif ($tokens->[$index] eq '}')
+                   {
+                   $index++;
+                   last;
+                   };
+   
+               $self->SkipRestOfStatement(\$index, \$lineNumber);
+               $self->TryToSkipWhitespace(\$index, \$lineNumber);
+               };
+   
+           if ($hasA && $hasB)
+               {  $prototype .= ' { ' . $aWord . ', ' . $bWord . ' }';  }
+           elsif ($hasA)
+               {  $prototype .= ' { ' . $aWord . ' }';  }
+           elsif ($hasB)
+               {  $prototype .= ' { ' . $bWord . ' }';  };
+   
+           $prototype = $self->NormalizePrototype($prototype);
+   
+           my $topicType = ( $isEvent ? ::TOPIC_EVENT() : ::TOPIC_PROPERTY() );
+   
+           $self->AddAutoTopic(NaturalDocs::Parser::ParsedTopic->New($topicType, $name,
+                                                                                                     $self->CurrentScope(), $self->CurrentUsing(),
+                                                                                                     $prototype,
+                                                                                                     undef, undef, $startLine));
+           }
+   
+   
+       # Functions, constructors, destructors, delegates.
+   
+       elsif ($tokens->[$index] eq '(')
+           {
+           # This should jump the parenthesis completely.
+           $self->GenericSkip(\$index, \$lineNumber);
+   
+           my $topicType = ( $isDelegate ? ::TOPIC_DELEGATE() : ::TOPIC_FUNCTION() );
+           my $prototype = $self->NormalizePrototype( $self->CreateString($startIndex, $index) );
+   
+           $self->AddAutoTopic(NaturalDocs::Parser::ParsedTopic->New($topicType, $name,
+                                                                                                     $self->CurrentScope(), $self->CurrentUsing(),
+                                                                                                     $prototype,
+                                                                                                     undef, undef, $startLine));
+   
+           $self->SkipRestOfStatement(\$index, \$lineNumber);
+           }
+   
+   
+       # Events without braces
+   
+       elsif ($isEvent && $tokens->[$index] eq ';')
+           {
+           my $prototype = $self->NormalizePrototype( $self->CreateString($startIndex, $index) );
+   
+           $self->AddAutoTopic(NaturalDocs::Parser::ParsedTopic->New(::TOPIC_EVENT(), $name,
+                                                                                                     $self->CurrentScope(), $self->CurrentUsing(),
+                                                                                                     $prototype,
+                                                                                                     undef, undef, $startLine));
+           $index++;
+           }
+   
+       else
+           {  return undef;  };
+   
+   
+       # We succeeded if we got this far.
+   
+       $$indexRef = $index;
+       $$lineNumberRef = $lineNumber;
+   
+       return 1;
+       };
+   
+   
+   #
+   #   Function: TryToGetOverloadedOperator
+   #
+   #   Determines if the position is on an operator overload declaration, and if so, generates a topic for it, skips it, and returns true.
+   #
+   sub TryToGetOverloadedOperator #(indexRef, lineNumberRef)
+       {
+       my ($self, $indexRef, $lineNumberRef) = @_;
+       my $tokens = $self->Tokens();
+   
+       my $index = $$indexRef;
+       my $lineNumber = $$lineNumberRef;
+   
+       if ($self->TryToSkipAttributes(\$index, \$lineNumber))
+           {  $self->TryToSkipWhitespace(\$index, \$lineNumber);  };
+   
+       my $startIndex = $index;
+       my $startLine = $lineNumber;
+   
+       my @modifiers;
+   
+       while ($tokens->[$index] =~ /^[a-z]/i &&
+                 exists $functionModifiers{lc($tokens->[$index])} )
+           {
+           push @modifiers, lc($tokens->[$index]);
+           $index++;
+   
+           $self->TryToSkipWhitespace(\$index, \$lineNumber);
+           };
+   
+   
+       my $name;
+   
+   
+       # Casting operators.
+   
+       if (lc($tokens->[$index]) eq 'implicit' || lc($tokens->[$index]) eq 'explicit')
+           {
+           $index++;
+   
+           $self->TryToSkipWhitespace(\$index, \$lineNumber);
+   
+           if (lc($tokens->[$index]) ne 'operator')
+               {  return undef;  };
+   
+           $index++;
+           $self->TryToSkipWhitespace(\$index, \$lineNumber);
+   
+           $name = $self->TryToGetType(\$index, \$lineNumber);
+   
+           if (!defined $name)
+               {  return undef;  };
+           }
+   
+   
+       # Symbol operators.
+   
+       else
+           {
+           if (!$self->TryToGetType(\$index, \$lineNumber))
+               {  return undef;  };
+   
+           $self->TryToSkipWhitespace(\$index, \$lineNumber);
+   
+           if (lc($tokens->[$index]) ne 'operator')
+               {  return undef;  };
+   
+           $index++;
+   
+           $self->TryToSkipWhitespace(\$index, \$lineNumber);
+   
+           if (lc($tokens->[$index]) eq 'true' || lc($tokens->[$index]) eq 'false')
+               {
+               $name = $tokens->[$index];
+               $index++;
+               }
+           else
+               {
+               while ($tokens->[$index] =~ /^[\+\-\!\~\*\/\%\&\|\^\<\>\=]$/)
+                   {
+                   $name .= $tokens->[$index];
+                   $index++;
+                   };
+               };
+           };
+   
+       $self->TryToSkipWhitespace(\$index, \$lineNumber);
+   
+       if ($tokens->[$index] ne '(')
+           {  return undef;  };
+   
+       # This should skip the parenthesis completely.
+       $self->GenericSkip(\$index, \$lineNumber);
+   
+       my $prototype = $self->NormalizePrototype( $self->CreateString($startIndex, $index) );
+   
+       $self->AddAutoTopic(NaturalDocs::Parser::ParsedTopic->New(::TOPIC_FUNCTION(), 'operator ' . $name,
+                                                                                                 $self->CurrentScope(), $self->CurrentUsing(),
+                                                                                                 $prototype,
+                                                                                                 undef, undef, $startLine));
+   
+       $self->SkipRestOfStatement(\$index, \$lineNumber);
+   
+   
+       # We succeeded if we got this far.
+   
+       $$indexRef = $index;
+       $$lineNumberRef = $lineNumber;
+   
+       return 1;
+       };
+   
+   
+   #
+   #   Function: TryToGetVariable
+   #
+   #   Determines if the position is on a variable declaration statement, and if so, generates a topic for each variable, skips the
+   #   statement, and returns true.
+   #
+   #   Supported Syntaxes:
+   #
+   #       - Variables
+   #       - Constants
+   #
+   sub TryToGetVariable #(indexRef, lineNumberRef)
+       {
+       my ($self, $indexRef, $lineNumberRef) = @_;
+       my $tokens = $self->Tokens();
+   
+       my $index = $$indexRef;
+       my $lineNumber = $$lineNumberRef;
+   
+       if ($self->TryToSkipAttributes(\$index, \$lineNumber))
+           {  $self->TryToSkipWhitespace(\$index, \$lineNumber);  };
+   
+       my $startIndex = $index;
+       my $startLine = $lineNumber;
+   
+       my @modifiers;
+   
+       while ($tokens->[$index] =~ /^[a-z]/i &&
+                 exists $variableModifiers{lc($tokens->[$index])} )
+           {
+           push @modifiers, lc($tokens->[$index]);
+           $index++;
+   
+           $self->TryToSkipWhitespace(\$index, \$lineNumber);
+           };
+   
+       my $type;
+       if (lc($tokens->[$index]) eq 'const')
+           {
+           $type = ::TOPIC_CONSTANT();
+           $index++;
+           $self->TryToSkipWhitespace(\$index, \$lineNumber);
+           }
+       else
+           {
+           $type = ::TOPIC_VARIABLE();
+           };
+   
+       if (!$self->TryToGetType(\$index, \$lineNumber))
+           {  return undef;  };
+   
+       my $endTypeIndex = $index;
+   
+       $self->TryToSkipWhitespace(\$index, \$lineNumber);
+   
+       my @names;
+   
+       for (;;)
+           {
+           my $name;
+   
+           while ($tokens->[$index] =~ /^[a-z\@\_]/i)
+               {
+               $name .= $tokens->[$index];
+               $index++;
+               };
+   
+           $self->TryToSkipWhitespace(\$index, \$lineNumber);
+   
+           if ($tokens->[$index] eq '=')
+               {
+               do
+                   {
+                   $self->GenericSkip(\$index, \$lineNumber);
+                   }
+               while ($tokens->[$index] ne ',' && $tokens->[$index] ne ';');
+               };
+   
+           push @names, $name;
+   
+           if ($tokens->[$index] eq ';')
+               {
+               $index++;
+               last;
+               }
+           elsif ($tokens->[$index] eq ',')
+               {
+               $index++;
+               $self->TryToSkipWhitespace(\$index, \$lineNumber);
+               }
+           else
+               {  return undef;  };
+           };
+   
+   
+       # We succeeded if we got this far.
+   
+       my $prototypePrefix = $self->CreateString($startIndex, $endTypeIndex);
+   
+       foreach my $name (@names)
+           {
+           my $prototype = $self->NormalizePrototype( $prototypePrefix . ' ' . $name );
+   
+           $self->AddAutoTopic(NaturalDocs::Parser::ParsedTopic->New($type, $name,
+                                                                                                     $self->CurrentScope(), $self->CurrentUsing(),
+                                                                                                     $prototype,
+                                                                                                     undef, undef, $startLine));
+           };
+   
+       $$indexRef = $index;
+       $$lineNumberRef = $lineNumber;
+   
+       return 1;
+       };
+   
+   
+   #
+   #   Function: TryToGetEnum
+   #
+   #   Determines if the position is on an enum declaration statement, and if so, generates a topic for it.
+   #
+   #   Supported Syntaxes:
+   #
+   #       - Enums
+   #       - Enums with declared types
+   #
+   #   Unsupported:
+   #
+   #       - Documenting the members automatically
+   #
+   sub TryToGetEnum #(indexRef, lineNumberRef)
+       {
+       my ($self, $indexRef, $lineNumberRef) = @_;
+       my $tokens = $self->Tokens();
+   
+       my $index = $$indexRef;
+       my $lineNumber = $$lineNumberRef;
+   
+       if ($self->TryToSkipAttributes(\$index, \$lineNumber))
+           {  $self->TryToSkipWhitespace(\$index, \$lineNumber);  };
+   
+       my $startIndex = $index;
+       my $startLine = $lineNumber;
+   
+       my @modifiers;
+   
+       while ($tokens->[$index] =~ /^[a-z]/i &&
+                 exists $variableModifiers{lc($tokens->[$index])} )
+           {
+           push @modifiers, lc($tokens->[$index]);
+           $index++;
+   
+           $self->TryToSkipWhitespace(\$index, \$lineNumber);
+           };
+   
+       if (lc($tokens->[$index]) ne 'enum')
+           {  return undef;  }
+   
+       $index++;
+       $self->TryToSkipWhitespace(\$index, \$lineNumber);
+   
+       my $name;
+   
+       while ($tokens->[$index] =~ /^[a-z\@\_]/i)
+           {
+           $name .= $tokens->[$index];
+           $index++;
+           };
+   
+       $self->TryToSkipWhitespace(\$index, \$lineNumber);
+   
+       if ($tokens->[$index] eq ':')
+           {
+           $index++;
+           $self->TryToSkipWhitespace(\$index, \$lineNumber);
+   
+           if (!exists $enumTypes{ lc($tokens->[$index]) })
+               {  return undef;  }
+   
+           $index++;
+           $self->TryToSkipWhitespace(\$index, \$lineNumber);
+           }
+   
+       if ($tokens->[$index] ne '{')
+           {  return undef;  }
+   
+       # We succeeded if we got this far.
+   
+       my $prototype = $self->CreateString($startIndex, $index);
+       $prototype = $self->NormalizePrototype( $prototype );
+   
+       $self->SkipRestOfStatement(\$index, \$lineNumber);
+   
+       $self->AddAutoTopic(NaturalDocs::Parser::ParsedTopic->New(::TOPIC_ENUMERATION(), $name,
+                                                                                                 $self->CurrentScope(), $self->CurrentUsing(),
+                                                                                                 $prototype,
+                                                                                                 undef, undef, $startLine));
+   
+       $$indexRef = $index;
+       $$lineNumberRef = $lineNumber;
+   
+       return 1;
+       };
+   
+   
+   #
+   #   Function: TryToGetType
+   #
+   #   Determines if the position is on a type identifier, and if so, skips it and returns it as a string.  This function does _not_ allow
+   #   modifiers.  You must take care of those beforehand.
+   #
+   sub TryToGetType #(indexRef, lineNumberRef)
+       {
+       my ($self, $indexRef, $lineNumberRef) = @_;
+       my $tokens = $self->Tokens();
+   
+       my $name;
+       my $index = $$indexRef;
+       my $lineNumber = $$lineNumberRef;
+   
+       while ($tokens->[$index] =~ /^[a-z\@\.\_]/i)
+           {
+           if (exists $impossibleTypeWords{ lc($tokens->[$index]) } && $name !~ /\@$/)
+               {  return undef;  };
+   
+           $name .= $tokens->[$index];
+           $index++;
+           };
+   
+       if (!defined $name)
+           {  return undef;  };
+   
+   	$self->TryToSkipWhitespace(\$index, \$lineNumber);
+   
+   	if ($tokens->[$index] eq '?')
+   		{
+   		$name .= '?';
+   		$index++;
+   
+   		$self->TryToSkipWhitespace(\$index, \$lineNumber);
+   		}
+   
+       if ($tokens->[$index] eq '<')
+       	{
+       	# XXX: This is half-assed.
+       	$name .= '<';
+       	$index++;
+   
+       	while ($index < scalar @$tokens && $tokens->[$index] ne '>')
+       		{
+       		$name .= $tokens->[$index];
+       		$index++;
+       		}
+   
+       	if ($index < scalar @$tokens)
+       		{
+       		$name .= '>';
+       		$index++;
+       		}
+       	else
+       		{  return undef;  }
+   
+   		$self->TryToSkipWhitespace(\$index, \$lineNumber);
+       	}
+   
+       while ($tokens->[$index] eq '[')
+           {
+           $name .= '[';
+           $index++;
+   
+           while ($tokens->[$index] eq ',')
+               {
+               $name .= ',';
+               $index++;
+               };
+   
+           if ($tokens->[$index] eq ']')
+               {
+               $name .= ']';
+               $index++;
+               }
+           else
+               {  return undef;  }
+           };
+   
+       $$indexRef = $index;
+       $$lineNumberRef = $lineNumber;
+   
+       return $name;
+       };
+   
+   
+   
+   ###############################################################################
+   # Group: Low Level Parsing Functions
+   
+   
+   #
+   #   Function: GenericSkip
+   #
+   #   Advances the position one place through general code.
+   #
+   #   - If the position is on a string, it will skip it completely.
+   #   - If the position is on an opening symbol, it will skip until the past the closing symbol.
+   #   - If the position is on whitespace (including comments and preprocessing directives), it will skip it completely.
+   #   - Otherwise it skips one token.
+   #
+   #   Parameters:
+   #
+   #       indexRef - A reference to the current index.
+   #       lineNumberRef - A reference to the current line number.
+   #
+   sub GenericSkip #(indexRef, lineNumberRef)
+       {
+       my ($self, $indexRef, $lineNumberRef) = @_;
+       my $tokens = $self->Tokens();
+   
+       # We can ignore the scope stack because we're just skipping everything without parsing, and we need recursion anyway.
+       if ($tokens->[$$indexRef] eq '{')
+           {
+           $$indexRef++;
+           $self->GenericSkipUntilAfter($indexRef, $lineNumberRef, '}');
+           }
+       elsif ($tokens->[$$indexRef] eq '(')
+           {
+           $$indexRef++;
+           $self->GenericSkipUntilAfter($indexRef, $lineNumberRef, ')');
+           }
+       elsif ($tokens->[$$indexRef] eq '[')
+           {
+           $$indexRef++;
+           $self->GenericSkipUntilAfter($indexRef, $lineNumberRef, ']');
+           }
+   
+       elsif ($self->TryToSkipWhitespace($indexRef, $lineNumberRef) ||
+               $self->TryToSkipString($indexRef, $lineNumberRef))
+           {
+           }
+   
+       else
+           {  $$indexRef++;  };
+       };
+   
+   
+   #
+   #   Function: GenericSkipUntilAfter
+   #
+   #   Advances the position via <GenericSkip()> until a specific token is reached and passed.
+   #
+   sub GenericSkipUntilAfter #(indexRef, lineNumberRef, token)
+       {
+       my ($self, $indexRef, $lineNumberRef, $token) = @_;
+       my $tokens = $self->Tokens();
+   
+       while ($$indexRef < scalar @$tokens && $tokens->[$$indexRef] ne $token)
+           {  $self->GenericSkip($indexRef, $lineNumberRef);  };
+   
+       if ($tokens->[$$indexRef] eq "\n")
+           {  $$lineNumberRef++;  };
+       $$indexRef++;
+       };
+   
+   
+   #
+   #   Function: SkipRestOfStatement
+   #
+   #   Advances the position via <GenericSkip()> until after the end of the current statement, which is defined as a semicolon or
+   #   a brace group.  Of course, either of those appearing inside parenthesis, a nested brace group, etc. don't count.
+   #
+   sub SkipRestOfStatement #(indexRef, lineNumberRef)
+       {
+       my ($self, $indexRef, $lineNumberRef) = @_;
+       my $tokens = $self->Tokens();
+   
+       while ($$indexRef < scalar @$tokens &&
+                $tokens->[$$indexRef] ne ';' &&
+                $tokens->[$$indexRef] ne '{')
+           {
+           $self->GenericSkip($indexRef, $lineNumberRef);
+           };
+   
+       if ($tokens->[$$indexRef] eq ';')
+           {  $$indexRef++;  }
+       elsif ($tokens->[$$indexRef] eq '{')
+           {  $self->GenericSkip($indexRef, $lineNumberRef);  };
+       };
+   
+   
+   #
+   #   Function: TryToSkipString
+   #   If the current position is on a string delimiter, skip past the string and return true.
+   #
+   #   Parameters:
+   #
+   #       indexRef - A reference to the index of the position to start at.
+   #       lineNumberRef - A reference to the line number of the position.
+   #
+   #   Returns:
+   #
+   #       Whether the position was at a string.
+   #
+   #   Syntax Support:
+   #
+   #       - Supports quotes, apostrophes, and at-quotes.
+   #
+   sub TryToSkipString #(indexRef, lineNumberRef)
+       {
+       my ($self, $indexRef, $lineNumberRef) = @_;
+       my $tokens = $self->Tokens();
+   
+       # The three string delimiters.  All three are Perl variables when preceded by a dollar sign.
+       if ($self->SUPER::TryToSkipString($indexRef, $lineNumberRef, '\'') ||
+           $self->SUPER::TryToSkipString($indexRef, $lineNumberRef, '"') )
+           {
+           return 1;
+           }
+       elsif ($tokens->[$$indexRef] eq '@' && $tokens->[$$indexRef+1] eq '"')
+           {
+           $$indexRef += 2;
+   
+           # We need to do at-strings manually because backslash characters are accepted as regular characters, and two consecutive
+           # quotes are accepted as well.
+   
+           while ($$indexRef < scalar @$tokens && !($tokens->[$$indexRef] eq '"' && $tokens->[$$indexRef+1] ne '"') )
+               {
+               if ($tokens->[$$indexRef] eq '"')
+                   {
+                   # This is safe because the while condition will only let through quote pairs.
+                   $$indexRef += 2;
+                   }
+               elsif ($tokens->[$$indexRef] eq "\n")
+                   {
+                   $$indexRef++;
+                   $$lineNumberRef++;
+                   }
+               else
+                   {
+                   $$indexRef++;
+                   };
+               };
+   
+           # Skip the closing quote.
+           if ($$indexRef < scalar @$tokens)
+               {  $$indexRef++;  };
+   
+           return 1;
+           }
+       else
+           {  return undef;  };
+       };
+   
+   
+   #
+   #   Function: TryToSkipAttributes
+   #   If the current position is on an attribute section, skip it and return true.  Skips multiple attribute sections if they appear
+   #   consecutively.
+   #
+   sub TryToSkipAttributes #(indexRef, lineNumberRef)
+       {
+       my ($self, $indexRef, $lineNumberRef) = @_;
+       my $tokens = $self->Tokens();
+   
+       my $success;
+   
+       while ($tokens->[$$indexRef] eq '[')
+           {
+           $success = 1;
+           $$indexRef++;
+           $self->GenericSkipUntilAfter($indexRef, $lineNumberRef, ']');
+           $self->TryToSkipWhitespace($indexRef, $lineNumberRef);
+           };
+   
+       return $success;
+       };
+   
+   
+   #
+   #   Function: TryToSkipWhitespace
+   #   If the current position is on a whitespace token, a line break token, a comment, or a preprocessing directive, it skips them
+   #   and returns true.  If there are a number of these in a row, it skips them all.
+   #
+   sub TryToSkipWhitespace #(indexRef, lineNumberRef)
+       {
+       my ($self, $indexRef, $lineNumberRef) = @_;
+       my $tokens = $self->Tokens();
+   
+       my $result;
+   
+       while ($$indexRef < scalar @$tokens)
+           {
+           if ($tokens->[$$indexRef] =~ /^[ \t]/)
+               {
+               $$indexRef++;
+               $result = 1;
+               }
+           elsif ($tokens->[$$indexRef] eq "\n")
+               {
+               $$indexRef++;
+               $$lineNumberRef++;
+               $result = 1;
+               }
+           elsif ($self->TryToSkipComment($indexRef, $lineNumberRef) ||
+                   $self->TryToSkipPreprocessingDirective($indexRef, $lineNumberRef))
+               {
+               $result = 1;
+               }
+           else
+               {  last;  };
+           };
+   
+       return $result;
+       };
+   
+   
+   #
+   #   Function: TryToSkipComment
+   #   If the current position is on a comment, skip past it and return true.
+   #
+   sub TryToSkipComment #(indexRef, lineNumberRef)
+       {
+       my ($self, $indexRef, $lineNumberRef) = @_;
+   
+       return ( $self->TryToSkipLineComment($indexRef, $lineNumberRef) ||
+                   $self->TryToSkipMultilineComment($indexRef, $lineNumberRef) );
+       };
+   
+   
+   #
+   #   Function: TryToSkipLineComment
+   #   If the current position is on a line comment symbol, skip past it and return true.
+   #
+   sub TryToSkipLineComment #(indexRef, lineNumberRef)
+       {
+       my ($self, $indexRef, $lineNumberRef) = @_;
+       my $tokens = $self->Tokens();
+   
+       if ($tokens->[$$indexRef] eq '/' && $tokens->[$$indexRef+1] eq '/')
+           {
+           $self->SkipRestOfLine($indexRef, $lineNumberRef);
+           return 1;
+           }
+       else
+           {  return undef;  };
+       };
+   
+   
+   #
+   #   Function: TryToSkipMultilineComment
+   #   If the current position is on an opening comment symbol, skip past it and return true.
+   #
+   sub TryToSkipMultilineComment #(indexRef, lineNumberRef)
+       {
+       my ($self, $indexRef, $lineNumberRef) = @_;
+       my $tokens = $self->Tokens();
+   
+       if ($tokens->[$$indexRef] eq '/' && $tokens->[$$indexRef+1] eq '*')
+           {
+           $self->SkipUntilAfter($indexRef, $lineNumberRef, '*', '/');
+           return 1;
+           }
+       else
+           {  return undef;  };
+       };
+   
+   
+   #
+   #   Function: TryToSkipPreprocessingDirective
+   #   If the current position is on a preprocessing directive, skip past it and return true.
+   #
+   sub TryToSkipPreprocessingDirective #(indexRef, lineNumberRef)
+       {
+       my ($self, $indexRef, $lineNumberRef) = @_;
+       my $tokens = $self->Tokens();
+   
+       if ($tokens->[$$indexRef] eq '#' && $self->IsFirstLineToken($$indexRef))
+           {
+           $self->SkipRestOfLine($indexRef, $lineNumberRef);
+           return 1;
+           }
+       else
+           {  return undef;  };
+       };
+   
+   
+   #
+   #   Function: PreprocessFile
+   #
+   #   Overridden to support end lines comments
+   #
+   sub PreprocessFile #(lines)
+       {
+       my ($self, $lines) = @_;
+   
+       my @newLines;
+       my $newLineNbr;
+       my $str;
+   
+       for (my $i = 0; $i < scalar @$lines; $i++)
+           {
+   	    if ($lines->[$i] =~ /^[ \t]*([_a-zA-Z][_a-zA-Z0-9]*)([ \t\*]*)([_a-zA-Z][_a-zA-Z0-9]*)[ \t]*;[ \t]*\/\*\+(.*)\*\//)
+   	    {
+   
+   		@newLines[$newLineNbr] = "/*";
+   		#print @newLines[$newLineNbr]."\n";
+   		$newLineNbr++;
+   
+   		@newLines[$newLineNbr] = "  variable: $3";
+   		#print @newLines[$newLineNbr]."\n";
+   		$newLineNbr++;
+   		
+   		$str = $4;
+   		$str =~ s/\+$//;
+   		#$str =~ s/^\+//;
+   		@newLines[$newLineNbr] = $str;
+   		#print @newLines[$newLineNbr]."\n";
+   		$newLineNbr++;
+   
+   		@newLines[$newLineNbr] = " */";
+   		#print @newLines[$newLineNbr]."\n";
+   		$newLineNbr++;
+   
+   		@newLines[$newLineNbr] = $lines->[$i];
+   		#print @newLines[$newLineNbr]."\n";
+   		$newLineNbr++;
+   
+   	    }
+   	    else 
+   	    {
+   		if (($lines->[$i] =~ /^[ \t]*([_a-zA-Z][_a-zA-Z0-9]*) ([ \t\*]*)([_a-zA-Z][_a-zA-Z0-9]*)([ \t*]*)([_a-zA-Z][_a-zA-Z0-9]*)[ \t]*;[ \t]*\/\*\+(.*)\*\//) && (exists $variableModifiers{lc($1)} || exists $variableModifiers{lc($3)}))
+   		{
+   		 
+   		    @newLines[$newLineNbr] = "/*";
+   		    #print @newLines[$newLineNbr]."\n";
+   		    $newLineNbr++;
+   		    
+   		    @newLines[$newLineNbr] = "  variable: $5";
+   		    #print @newLines[$newLineNbr]."\n";
+   		    $newLineNbr++;
+   		    
+   		    my $str = $6;
+   		    $str =~ s/\+$//;
+   		    #$str =~ s/^\+//;
+   		    @newLines[$newLineNbr] = $str;
+   		    #print @newLines[$newLineNbr]."\n";
+   		    $newLineNbr++;
+   		    
+   		    @newLines[$newLineNbr] = " */";
+   		    #print @newLines[$newLineNbr]."\n";
+   		    $newLineNbr++;
+   		    
+   		    @newLines[$newLineNbr] = $lines->[$i];
+   		    #print @newLines[$newLineNbr]."\n";
+   		    $newLineNbr++;
+   		    
+   		}
+   		else 
+   		{
+   
+   		    @newLines[$newLineNbr] = $lines->[$i];
+   		    $newLineNbr++;
+   		};
+   	    };
+           };
+   
+       for (my $i = 0; $i < scalar @newLines; $i++)
+           {
+   	    $lines->[$i] = @newLines[$i];
+   	}
+       };
+   
+   
+   1;

--- Config/Languages.txt	2008-05-06 02:08:58.000000000 +0200
+++ Config/Languages.txt	2008-06-11 16:58:10.000000000 +0200
@@ -109,14 +109,9 @@
 Language: C/C++
 
    Extensions: c cpp h hpp cxx hxx
+   Ignore Prefix in Index: @
    Ignore Function Prefix in Index: ~
-   Line Comment: //
-   Block Comment: /* */
-   Package Separator: ::
-   Enum Values: Under parent
-   Class Prototype Enders: ; {
-   Function Prototype Enders: ; {
-   Variable Prototype Enders: ; =
+   Full Language Support: NaturalDocs::Languages::C
 
 
 Language: C#
@@ -183,8 +178,8 @@
    Enum Values: Global
    Function Prototype Enders: , ; ) as As AS is Is IS
    Variable Prototype Enders: , ; ) := default Default DEFAULT
-   Database Trigger Prototype Enders: begin Begin BEGIN as As AS
    Database Index Prototype Enders: , ; )
+   Database Trigger Prototype Enders: begin Begin BEGIN as As AS
    Perl Package: NaturalDocs::Languages::PLSQL
 
 
--- Modules/NaturalDocs/Languages.pm	2008-03-18 17:43:22.000000000 +0100
+++ Modules/NaturalDocs/Languages.pm	2008-06-05 15:54:28.000000000 +0200
@@ -25,6 +25,7 @@
 
 use NaturalDocs::Languages::Perl;
 use NaturalDocs::Languages::CSharp;
+use NaturalDocs::Languages::C;
 use NaturalDocs::Languages::ActionScript;
 
 use NaturalDocs::Languages::Ada;
