瀏覽代碼

* updated version of the conversion script, used to generate the previously
committed cocoa unit conversions, and which can also be used to translate
the iOS SDK 3.2 headers
+ scripts (make-cocoa-headers.sh, make-ios-headers.sh) to (re)build the
Cocoa/iOS headers, along with skeleton directories that contain the
necessary helper files and a few required patches
+ frameworks.xml used by the conversion script
* updated build instructions

git-svn-id: trunk@16522 -

Jonas Maebe 14 年之前
父節點
當前提交
a880603816
共有 31 個文件被更改,包括 5592 次插入4527 次删除
  1. 26 2
      .gitattributes
  2. 6 4
      packages/cocoaint/utils/Make Cocoa Headers.txt
  3. 5 17
      packages/cocoaint/utils/Make iPhone Headers.txt
  4. 121 0
      packages/cocoaint/utils/cocoa-skel/src/CocoaAll.pas
  5. 58 0
      packages/cocoaint/utils/cocoa-skel/src/CoreData.pas
  6. 132 0
      packages/cocoaint/utils/cocoa-skel/src/InlineFunctions.inc
  7. 65 0
      packages/cocoaint/utils/cocoa-skel/src/UndefinedTypes.inc
  8. 69 0
      packages/cocoaint/utils/cocoa-skel/src/WebKit.pas
  9. 182 0
      packages/cocoaint/utils/cocoa-skel/src/appkit/AppKit.inc
  10. 0 0
      packages/cocoaint/utils/cocoa-skel/src/appkit/CIColor.inc
  11. 28 0
      packages/cocoaint/utils/cocoa-skel/src/coredata/CoreData.inc
  12. 131 0
      packages/cocoaint/utils/cocoa-skel/src/foundation/Foundation.inc
  13. 52 0
      packages/cocoaint/utils/cocoa-skel/src/quartzcore/QuartzCore.inc
  14. 10 0
      packages/cocoaint/utils/cocoa-skel/src/webkit/UndefinedTypes.inc
  15. 167 0
      packages/cocoaint/utils/cocoa-skel/src/webkit/WebKit.inc
  16. 132 0
      packages/cocoaint/utils/frameworks.xml
  17. 30 0
      packages/cocoaint/utils/make-cocoa-headers.sh
  18. 43 0
      packages/cocoaint/utils/make-ios-headers.sh
  19. 56 105
      packages/cocoaint/utils/parser.php
  20. 0 4163
      packages/cocoaint/utils/pascocoa_parser.php
  21. 252 0
      packages/cocoaint/utils/patches/cocoa-coredata-webkit.patch
  22. 52 0
      packages/cocoaint/utils/patches/uikit.patch
  23. 176 236
      packages/cocoaint/utils/source/objp_parser.php
  24. 3443 0
      packages/cocoaint/utils/source/pascocoa_parser.php
  25. 4 0
      packages/cocoaint/utils/uikit-skel/src/InlineFunctions.inc
  26. 69 0
      packages/cocoaint/utils/uikit-skel/src/UndefinedTypes.inc
  27. 79 0
      packages/cocoaint/utils/uikit-skel/src/foundation/Foundation.inc
  28. 106 0
      packages/cocoaint/utils/uikit-skel/src/iPhoneAll.pas
  29. 3 0
      packages/cocoaint/utils/uikit-skel/src/opengles/OpenGLES.inc
  30. 19 0
      packages/cocoaint/utils/uikit-skel/src/quartzcore/QuartzCore.inc
  31. 76 0
      packages/cocoaint/utils/uikit-skel/src/uikit/UIKit.inc

+ 26 - 2
.gitattributes

@@ -1559,14 +1559,38 @@ packages/cocoaint/src/webkit/WebView.inc svneol=native#text/plain
 packages/cocoaint/utils/Make[!!-~]Cocoa[!!-~]Headers.txt svneol=native#text/plain
 packages/cocoaint/utils/Make[!!-~]iPhone[!!-~]Headers.txt svneol=native#text/plain
 packages/cocoaint/utils/Using[!!-~]Installer[!!-~]Script.txt svneol=native#text/plain
+packages/cocoaint/utils/cocoa-skel/src/CocoaAll.pas svneol=native#text/plain
+packages/cocoaint/utils/cocoa-skel/src/CoreData.pas svneol=native#text/plain
+packages/cocoaint/utils/cocoa-skel/src/InlineFunctions.inc svneol=native#text/plain
+packages/cocoaint/utils/cocoa-skel/src/UndefinedTypes.inc svneol=native#text/plain
+packages/cocoaint/utils/cocoa-skel/src/WebKit.pas svneol=native#text/plain
+packages/cocoaint/utils/cocoa-skel/src/appkit/AppKit.inc svneol=native#text/plain
+packages/cocoaint/utils/cocoa-skel/src/appkit/CIColor.inc svneol=native#text/plain
+packages/cocoaint/utils/cocoa-skel/src/coredata/CoreData.inc svneol=native#text/plain
+packages/cocoaint/utils/cocoa-skel/src/foundation/Foundation.inc svneol=native#text/plain
+packages/cocoaint/utils/cocoa-skel/src/quartzcore/QuartzCore.inc svneol=native#text/plain
+packages/cocoaint/utils/cocoa-skel/src/webkit/UndefinedTypes.inc svneol=native#text/plain
+packages/cocoaint/utils/cocoa-skel/src/webkit/WebKit.inc svneol=native#text/plain
+packages/cocoaint/utils/frameworks.xml svneol=native#text/plain
 packages/cocoaint/utils/install_objp.sh svneol=native#text/plain
 packages/cocoaint/utils/iphone/iPhone[!!-~]Parser.txt svneol=native#text/plain
 packages/cocoaint/utils/iphone/objp_parser.php svneol=native#text/plain
 packages/cocoaint/utils/iphone/parser.php svneol=native#text/plain
 packages/cocoaint/utils/iphone/pascocoa_parser.php svneol=native#text/plain
-packages/cocoaint/utils/objp_parser.php svneol=native#text/plain
+packages/cocoaint/utils/make-cocoa-headers.sh svneol=native#text/plain
+packages/cocoaint/utils/make-ios-headers.sh svneol=native#text/plain
 packages/cocoaint/utils/parser.php svneol=native#text/plain
-packages/cocoaint/utils/pascocoa_parser.php svneol=native#text/plain
+packages/cocoaint/utils/patches/cocoa-coredata-webkit.patch svneol=native#text/plain
+packages/cocoaint/utils/patches/uikit.patch svneol=native#text/plain
+packages/cocoaint/utils/source/objp_parser.php svneol=native#text/plain
+packages/cocoaint/utils/source/pascocoa_parser.php svneol=native#text/plain
+packages/cocoaint/utils/uikit-skel/src/InlineFunctions.inc svneol=native#text/plain
+packages/cocoaint/utils/uikit-skel/src/UndefinedTypes.inc svneol=native#text/plain
+packages/cocoaint/utils/uikit-skel/src/foundation/Foundation.inc svneol=native#text/plain
+packages/cocoaint/utils/uikit-skel/src/iPhoneAll.pas svneol=native#text/plain
+packages/cocoaint/utils/uikit-skel/src/opengles/OpenGLES.inc svneol=native#text/plain
+packages/cocoaint/utils/uikit-skel/src/quartzcore/QuartzCore.inc svneol=native#text/plain
+packages/cocoaint/utils/uikit-skel/src/uikit/UIKit.inc svneol=native#text/plain
 packages/dbus/Makefile svneol=native#text/plain
 packages/dbus/Makefile.fpc svneol=native#text/plain
 packages/dbus/examples/Makefile svneol=native#text/plain

+ 6 - 4
packages/cocoaint/utils/Make Cocoa Headers.txt

@@ -1,4 +1,6 @@
-1) cd to the directory which contains parser.php
-2) php parser.php -cocoa -root="/usr/local/lib/fpc/2.5.1/units/i386-darwin/cocoaint/src"
-	
-	Note: -root is the path to the directory which contains the base appkit and foundation folders. These folders come in the FPC distribution with some hand parsed headers and the master include units for each framework.
+To (re)build the Objective-Pascal Cocoa headers from source (note: only
+tested against the Mac OS X 10.6 headers):
+1) cd to the directory which contains parser.php (this directory)
+2) ./make-cocoa-headers.sh
+
+The built headers will be placed under cocoa-skel/src

+ 5 - 17
packages/cocoaint/utils/Make iPhone Headers.txt

@@ -2,23 +2,11 @@ It is against the Apple license to distribute even derivatives of the iPhone hea
 
 Please note you must download the iPhone SDK (2GB+) from Apple's website (https://developer.apple.com/iphone), which contains the headers. Once the files are installed make sure the following SDK is available at this location:
 
-/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.2.1.sdk/System/Library/Frameworks/UIKit.framework/Headers
+/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.2.sdk/System/Library/Frameworks/UIKit.framework/Headers
 
-1) cd to the directory which contains parser.php
-2) php parser.php -iphone -root="/Developer/ObjectivePascal/Headers"
-	
-	Note: -root is the path to the directory which contains the base appkit and foundation folders. These folders come in the FPC distribution with some hand parsed headers and the master include units for each framework. In SVN they reside at packages/cocoaint/src.
-
-3) Finally some handing coding must be done:
-
-	1) UITextInputTraits in UITextInputTraits.inc must be changed to UITextInputTraitsProtocol.
+To build the iOS Objective-Pascal headers (only supported for the iOS 3.2 SDK headers at this time, other SDK versinos will probably result in errors and require manual modification),
+1) cd to the directory which contains parser.php (the current directory)
+2) ./make-ios-headers.sh
 
-		UITextField.inc(80,32) Error: Identifier not found "UITextInputTraits"
-		UITextField.inc(81,39) Error: Identifier not found "UITextInputTraits"
+The built headers will be placed under uikit-skel/src.
 	
-	2) In UIAcceleration.inc you must comment out the follow 3 methods. Bug in FPC has been filed.
-	
-		function x: UIAccelerationValue; message 'x';
-    		function y: UIAccelerationValue; message 'y';
-    		function z: UIAccelerationValue; message 'z';
-

+ 121 - 0
packages/cocoaint/utils/cocoa-skel/src/CocoaAll.pas

@@ -0,0 +1,121 @@
+unit CocoaAll;
+
+{$mode delphi}
+{$modeswitch objectivec1}
+{$modeswitch cvar} { for "external" after the semi-colon with external vars }
+
+interface
+
+uses 
+  ctypes,
+  AEDataModel,IconsCore,
+  CFBase, CFArray, CFBag , CFCharacterSet, CFData, CFDate, CFDictionary, CFNumber ,CFPropertyList, CFSet, CFString, CFStringEncodingExt, CFTimeZone, CFTree, CFURL, CFXMLNode, CFXMLParser, CFMachPort, CFMessagePort, CFRunLoop, CFSocket, CFBinaryHeap, CFBitVector, CFBundle, CFByteOrders, CFPlugIn, CFPreferences, CFURLAccess, CFUUID, CFLocale, CFStream, CFDateFormatter, CFNumberFormatter, CFCalendar, CFUserNotification, CFNotificationCenter, CFAttributedString, CFNetworkErrorss,
+  CGBase, CGAffineTransforms, CGBitmapContext, CGColor, CGColorSpace, CGContext, CGDataConsumer, CGDataProvider, CGDirectDisplay, CGDirectPalette, CGDisplayConfiguration, CGDisplayFades, CGErrors, CGEvent, CGEventSource, CGEventTypes, CGFont, CGFunction, CGGLContext, CGGeometry, CGImage, CGLayer, CGPDFArray, CGPDFContentStream, CGPDFContext, CGPDFDictionary, CGPDFDocument, CGPDFObject, CGPDFOperatorTable, CGPDFPage, CGPDFScanner, CGPDFStream, CGPDFString, CGPSConverter, CGPath, CGPattern, CGRemoteOperation, CGSession, CGShading, CGWindowLevels,
+  CVBase,CVImageBuffer,
+  IOSurfaceAPI,
+  SecBase, SecTrust,
+  MacTypes, MacOSXPosix,
+  macgl, CGLTypes,
+  AnonClassDefinitionsQuartzcore;
+  
+{$linkframework Cocoa}
+{$define INTERFACE}
+
+{$include UndefinedTypes.inc}
+// also includes the ones for foundation and appkit
+{$include quartzcore/AnonIncludeClassDefinitionsQuartzcore.inc}
+
+{$define HEADER}
+{$include foundation/Foundation.inc}
+{$include quartzcore/QuartzCore.inc}
+{$include appkit/AppKit.inc}
+{$undef HEADER}
+
+{$define TYPES}
+{$include foundation/Foundation.inc}
+{$include quartzcore/QuartzCore.inc}
+{$include appkit/AppKit.inc}
+{$undef TYPES}
+
+{$define RECORDS}
+{$include foundation/Foundation.inc}
+{$include quartzcore/QuartzCore.inc}
+{$include appkit/AppKit.inc}
+{$undef RECORDS}
+
+type
+{$define FORWARD}
+{$include foundation/Foundation.inc}
+{$include quartzcore/QuartzCore.inc}
+{$include appkit/AppKit.inc}
+{$undef FORWARD}
+
+{$define PROTOCOLS}
+{$include foundation/Foundation.inc}
+{$include quartzcore/QuartzCore.inc}
+{$include appkit/AppKit.inc}
+{$undef PROTOCOLS}
+
+{$define CLASSES}
+{$include foundation/Foundation.inc}
+{$include quartzcore/QuartzCore.inc}
+{$include appkit/AppKit.inc}
+{$undef CLASSES}
+ 
+{$define FUNCTIONS}
+{$include foundation/Foundation.inc}
+{$include quartzcore/QuartzCore.inc}
+{$include appkit/AppKit.inc}
+{$undef FUNCTIONS}
+
+{$define EXTERNAL_SYMBOLS}
+{$include foundation/Foundation.inc}
+{$include quartzcore/QuartzCore.inc}
+{$include appkit/AppKit.inc}
+{$undef EXTERNAL_SYMBOLS}
+
+{$define USER_PATCHES}
+{$include foundation/Foundation.inc}
+{$include quartzcore/QuartzCore.inc}
+{$include appkit/AppKit.inc}
+{$undef USER_PATCHES}
+
+{ Inline functions }
+function NSSTR (inString: PChar): NSString;
+function NSMakeRange (loc: NSUInteger; len: NSUInteger): NSRange;
+function NSMaxRange (range: NSRange): NSUInteger;
+function NSLocationInRange (loc: NSUInteger; range: NSRange): boolean;
+function NSEqualRanges (range1, range2: NSRange): boolean;
+function NSMakePoint (x: CGFloat; y: CGFloat): NSPoint;
+function NSMakeSize(w: CGFloat; h: CGFloat): NSSize;
+function NSMakeRect(x, y: CGFloat; w, h: CGFloat): NSRect;
+function NSMaxX (aRect: NSRect): CGFloat;
+function NSMaxY (aRect: NSRect): CGFloat;
+function NSMidX (aRect: NSRect): CGFloat;
+function NSMidY (aRect: NSRect): CGFloat;
+function NSMinX (aRect: NSRect): CGFloat;
+function NSMinY (aRect: NSRect): CGFloat;
+function NSWidth (aRect: NSRect): CGFloat;
+function NSHeight (aRect: NSRect): CGFloat;
+function NSRectFromCGRect (aRect: CGRect): NSRect;
+function NSRectToCGRect (aRect: NSRect): CGRect;
+function NSPointFromCGPoint (aPoint: CGPoint): NSPoint;
+function NSPointToCGPoint (aPoint: NSPoint): CGPoint;
+function NSSizeFromCGSize(aSize: CGSize): NSSize;
+function NSSizeToCGSize(aSize: NSSize): CGSize;
+
+{$undef INTERFACE}
+
+implementation
+{$define IMPLEMENTATION}
+
+{$include InlineFunctions.inc}
+
+{$define USER_PATCHES}
+{$include foundation/Foundation.inc}
+{$include quartzcore/QuartzCore.inc}
+{$include appkit/AppKit.inc}
+{$undef USER_PATCHES}
+
+{$undef IMPLEMENTATION}
+end.

+ 58 - 0
packages/cocoaint/utils/cocoa-skel/src/CoreData.pas

@@ -0,0 +1,58 @@
+{$mode delphi}
+{$modeswitch cvar}
+{$modeswitch objectivec1}
+unit CoreData;
+interface
+uses
+	ctypes, CocoaAll;
+{$linkframework Cocoa}	{ Cocoa is "umbrella" fremework, includes CoreData }
+{$define INTERFACE}
+
+{$include coredata/AnonIncludeClassDefinitionsCoredata.inc}
+
+{$define HEADER}
+{$include coredata/CoreData.inc}
+{$undef HEADER}
+
+{$define TYPES}
+{$include coredata/CoreData.inc}
+{$undef TYPES}
+
+{$define RECORDS}
+{$include coredata/CoreData.inc}
+{$undef RECORDS}
+
+{$define FORWARD}
+{$include coredata/CoreData.inc}
+{$undef FORWARD}
+
+{$define PROTOCOLS}
+{$include coredata/CoreData.inc}
+{$undef PROTOCOLS}
+
+{$define CLASSES}
+{$include coredata/CoreData.inc}
+{$undef CLASSES}
+
+{$define FUNCTIONS}
+{$include coredata/CoreData.inc}
+{$undef FUNCTIONS}
+
+{$define EXTERNAL_SYMBOLS}
+{$include coredata/CoreData.inc}
+{$undef EXTERNAL_SYMBOLS}
+
+{$define USER_PATCHES}
+{$include coredata/CoreData.inc}
+{$undef USER_PATCHES}
+
+
+{$undef INTERFACE}
+
+implementation
+
+{$define IMPLEMENTATION}
+
+{$undef IMPLEMENTATION}
+
+end.

+ 132 - 0
packages/cocoaint/utils/cocoa-skel/src/InlineFunctions.inc

@@ -0,0 +1,132 @@
+
+function NSMakeRange (loc: NSUInteger; len: NSUInteger): NSRange;
+begin
+ result.location := loc;
+ result.length := len;
+end;
+
+function NSMaxRange (range: NSRange): NSUInteger;
+begin
+ result := range.location + range.length;
+end;
+
+function NSLocationInRange (loc: NSUInteger; range: NSRange): boolean;
+begin
+ if (loc <= range.location + range.length) and (loc >= range.location) then
+  result := true
+ else
+  result := false;
+end;
+
+function NSEqualRanges (range1, range2: NSRange): boolean;
+begin
+ if (range1.location = range2.location) and (range1.length = range2.length) then
+  result := true
+ else
+  result := false;
+end;
+
+function NSMakePoint (x: CGFloat; y: CGFloat): NSPoint;
+begin
+  result.y := y;
+  result.x := x;
+end;
+
+function NSMakeSize(w: CGFloat; h: CGFloat): NSSize;
+begin
+  result.width := w;
+  result.height := h;
+end;
+
+function NSMakeRect(x, y: CGFloat; w, h: CGFloat): NSRect;
+begin
+  result.origin.x := x;
+  result.origin.y := y;
+  result.size.width := w;
+  result.size.height := h;
+end;
+
+function NSMaxX (aRect: NSRect): CGFloat;
+begin
+  result := aRect.origin.x + aRect.size.width;
+end;
+
+function NSMaxY (aRect: NSRect): CGFloat;
+begin
+  result := aRect.origin.y + aRect.size.height;
+end;
+
+function NSMidX (aRect: NSRect): CGFloat;
+begin
+  result := (aRect.origin.x + aRect.size.width) * 0.5 ;
+end;
+
+function NSMidY (aRect: NSRect): CGFloat;
+begin
+  result := (aRect.origin.y + aRect.size.height) * 0.5 ;
+end;
+
+function NSMinX (aRect: NSRect): CGFloat;
+begin
+  result := aRect.origin.x;
+end;
+
+function NSMinY (aRect: NSRect): CGFloat;
+begin
+  result := aRect.origin.y;
+end;
+
+function NSWidth (aRect: NSRect): CGFloat;
+begin
+  result := aRect.size.width;
+end;
+
+function NSHeight (aRect: NSRect): CGFloat;
+begin
+  result := aRect.size.height;
+end;
+
+function NSRectFromCGRect (aRect: CGRect): NSRect;
+begin
+  result.origin.x := aRect.origin.x;
+  result.origin.y := aRect.origin.y;
+  result.size.width := aRect.size.width;
+  result.size.height := aRect.size.height;
+end;
+
+function NSRectToCGRect (aRect: NSRect): CGRect;
+begin
+  result.origin.x := aRect.origin.x;
+  result.origin.y := aRect.origin.y;
+  result.size.width := aRect.size.width;
+  result.size.height := aRect.size.height;
+end;
+
+function NSPointFromCGPoint (aPoint: CGPoint): NSPoint;
+begin
+  result.y := aPoint.y;
+  result.x := aPoint.x;
+end;
+
+function NSPointToCGPoint (aPoint: NSPoint): CGPoint;
+begin
+  result.y := aPoint.y;
+  result.x := aPoint.x;
+end;
+
+function NSSizeFromCGSize(aSize: CGSize): NSSize;
+begin
+  result.width := aSize.width;
+  result.height := aSize.height;
+end;
+
+function NSSizeToCGSize(aSize: NSSize): CGSize;
+begin
+  result.width := aSize.width;
+  result.height := aSize.height;
+end;
+
+function NSSTR (inString: PChar): NSString;
+begin
+  Result := NSString(CFSTR(inString));
+end;

+ 65 - 0
packages/cocoaint/utils/cocoa-skel/src/UndefinedTypes.inc

@@ -0,0 +1,65 @@
+type
+  __NSAppleEventManagerSuspension = record end;
+  IBAction = Pointer;
+  objc_protocol = protocol;
+  idptr = ^id;
+  idptrptr = ^idptr;
+  SELptr = ^SEL;
+
+{ Variable argument list - disabled for Pascal }
+type
+ va_list_rec = record
+ end;
+ va_list = ^va_list_rec;
+
+{ Private instance variable types }
+type
+ _NSImageCellAnimationState = Pointer;
+ _CGLPBufferObject = Pointer;
+ PATHSEGMENT = Pointer;		{from NSBezierPath.h what is this???}
+ 
+{ from CoreData }
+type
+ NSAttributeType = NSUInteger;
+
+{ Pointer C-Types }
+
+{ An array of objects }
+type
+  NSObjectArrayOfObjects = array[0..(high(longint) div sizeof(id))-1] of id;
+  NSObjectArrayOfObjectsPtr = ^NSObjectArrayOfObjects;
+
+{ Cocoa types }
+const
+ UINT_MAX = high(culong);
+// 7.18.2.4 Limits of integer types capable of holding object pointers
+ INTPTR_MIN = low(ptrint);
+ INTPTR_MAX = high(ptrint);
+ UINTPTR_MAX = high(ptruint);
+// 7.18.2.5 Limits of greatest-width integer types
+ INTMAX_MIN = low(int64);
+ INTMAX_MAX = high(int64);
+ UINTMAX_MAX = high(qword);
+// 7.18.3 "Other"
+ PTRDIFF_MIN = INTPTR_MIN;
+ PTRDIFF_MAX = INTPTR_MAX;
+
+{ from IOKit (not yet part of univint) }
+const
+ NX_TABLET_POINTER_UNKNOWN = 0;
+ NX_TABLET_POINTER_PEN = 1;
+ NX_TABLET_POINTER_CURSOR = 2;
+ NX_TABLET_POINTER_ERASER = 3;
+ 
+ NX_SUBTYPE_DEFAULT = 0;
+ NX_SUBTYPE_TABLET_POINT = 1;
+ NX_SUBTYPE_TABLET_PROXIMITY = 2;
+ NX_SUBTYPE_MOUSE_TOUCH = 3;
+ 
+ NX_TABLET_BUTTON_PENTIPMASK = $0001;
+ NX_TABLET_BUTTON_PENLOWERSIDEMASK = $0002;
+ NX_TABLET_BUTTON_PENUPPERSIDEMASK = $0004;
+  
+{ Parser hacks - these types should never exist }
+type
+  __NSAppleEventManagerSuspensionPtr = Pointer;

+ 69 - 0
packages/cocoaint/utils/cocoa-skel/src/WebKit.pas

@@ -0,0 +1,69 @@
+unit WebKit;
+
+{$mode delphi}
+{$modeswitch cvar}
+{$modeswitch objectivec1}
+
+interface
+
+{$linkframework WebKit}
+
+uses
+  ctypes, CocoaAll,
+  CFBase, CFArray, CFBag , CFCharacterSet, CFData, CFDate, CFDictionary, CFNumber ,CFPropertyList, CFSet, CFString, CFStringEncodingExt, CFTimeZone, CFTree, CFURL, CFXMLNode, CFXMLParser, CFMachPort, CFMessagePort, CFRunLoop, CFSocket, CFBinaryHeap, CFBitVector, CFBundle, CFByteOrders, CFPlugIn, CFPreferences, CFURLAccess, CFUUID, CFLocale, CFStream, CFDateFormatter, CFNumberFormatter, CFCalendar, CFUserNotification, CFNotificationCenter, CFAttributedString,
+  CGBase, CGAffineTransforms, CGBitmapContext, CGColor, CGColorSpace, CGContext, CGDataConsumer, CGDataProvider, CGDirectDisplay, CGDirectPalette, CGDisplayConfiguration, CGDisplayFades, CGErrors, CGEvent, CGEventSource, CGEventTypes, CGFont, CGFunction, CGGLContext, CGGeometry, CGImage, CGLayer, CGPDFArray, CGPDFContentStream, CGPDFContext, CGPDFDictionary, CGPDFDocument, CGPDFObject, CGPDFOperatorTable, CGPDFPage, CGPDFScanner, CGPDFStream, CGPDFString, CGPSConverter, CGPath, CGPattern, CGRemoteOperation, CGSession, CGShading, CGWindowLevels,
+  MacTypes,
+  AnonClassDefinitionsWebkit;
+  
+{$define INTERFACE}
+
+{$include webkit/UndefinedTypes.inc}
+{$include webkit/AnonIncludeClassDefinitionsWebkit.inc}
+
+{$define HEADER}
+{$include webkit/WebKit.inc}
+{$undef HEADER}
+
+{$define TYPES}
+{$include webkit/WebKit.inc}
+{$undef TYPES}
+
+{$define RECORDS}
+{$include webkit/WebKit.inc}
+{$undef RECORDS}
+
+type
+{$define FORWARD}
+{$include webkit/WebKit.inc}
+{$undef FORWARD}
+
+{$define PROTOCOLS}
+{$include webkit/WebKit.inc}
+{$undef PROTOCOLS}
+
+{$define CLASSES}
+{$include webkit/WebKit.inc}
+{$undef CLASSES}
+ 
+{$define FUNCTIONS}
+{$include webkit/WebKit.inc}
+{$undef FUNCTIONS}
+
+{$define EXTERNAL_SYMBOLS}
+{$include webkit/WebKit.inc}
+{$undef EXTERNAL_SYMBOLS}
+
+{$define USER_PATCHES}
+{$include webkit/WebKit.inc}
+{$undef USER_PATCHES}
+
+{$undef INTERFACE}
+implementation
+{$define IMPLEMENTATION}
+
+{$define USER_PATCHES}
+{$include webkit/WebKit.inc}
+{$undef USER_PATCHES}
+
+{$undef IMPLEMENTATION}
+end.

+ 182 - 0
packages/cocoaint/utils/cocoa-skel/src/appkit/AppKit.inc

@@ -0,0 +1,182 @@
+
+{ Added for compatibility }
+{$include CIColor.inc}
+
+{ === From OS 10.5 === }
+{$include NSResponder.inc} 
+{$include NSGraphicsContext.inc} 
+{$include NSAccessibility.inc} 
+{$include NSAlert.inc} 
+{$include NSAnimationContext.inc} 
+{$include NSAppleScriptExtensions.inc} 
+{$include NSApplication.inc} 
+{$include NSParagraphStyle.inc} 
+{$include NSCell.inc} 
+{$include NSActionCell.inc} 
+{$include NSButtonCell.inc} 
+{$include NSDockTile.inc} 
+{$include NSFont.inc} 
+{$include NSFontDescriptor.inc} 
+{$include NSFontManager.inc} 
+{$include NSFormCell.inc} 
+{$include NSMenu.inc} 
+{$include NSColor.inc} 
+{$include NSColorSpace.inc} 
+{$include NSBrowserCell.inc} 
+{$include NSColorList.inc} 
+{$include NSColorPicking.inc} 
+{$include NSColorPicker.inc} 
+{$include NSCursor.inc} 
+{$include NSDocument.inc} 
+{$include NSDocumentController.inc} 
+{$include NSDragging.inc} 
+{$include NSErrors.inc} 
+{$include NSEvent.inc} 
+{$include NSFileWrapper.inc} 
+{$include NSHelpManager.inc} 
+{$include NSGradient.inc} 
+{$include NSGraphics.inc} 
+{$include NSImage.inc} 
+{$include NSImageCell.inc} 
+{$include NSImageRep.inc} 
+{$include NSBitmapImageRep.inc} 
+{$include NSCachedImageRep.inc} 
+{$include NSCIImageRep.inc} 
+{$include NSCustomImageRep.inc} 
+{$include NSEPSImageRep.inc} 
+{$include NSNib.inc} 
+{$include NSNibLoading.inc} 
+{$include NSPrinter.inc} 
+{$include NSSpeechRecognizer.inc} 
+{$include NSSpeechSynthesizer.inc} 
+{$include NSSpellChecker.inc} 
+{$include NSPageLayout.inc} 
+{$include NSPasteboard.inc} 
+{$include NSPrintInfo.inc} 
+{$include NSPrintOperation.inc} 
+{$include NSScreen.inc} 
+{$include NSSliderCell.inc} 
+{$include NSSpellProtocol.inc} 
+{$include NSTextFieldCell.inc} 
+{$include NSTokenFieldCell.inc} 
+{$include NSTrackingArea.inc} 
+{$include NSView.inc} 
+{$include NSMenuItem.inc} 
+{$include NSScrollView.inc} 
+{$include NSSplitView.inc} 
+{$include NSClipView.inc} 
+{$include NSText.inc} 
+{$include NSViewController.inc} 
+{$include NSControl.inc} 
+{$include NSButton.inc}
+{$include NSPopUpButton.inc} 
+{$include NSImageView.inc} 
+{$include NSColorWell.inc} 
+{$include NSBrowser.inc} 
+{$include NSMatrix.inc}
+{$include NSForm.inc} 
+{$include NSBox.inc}
+{$include NSScroller.inc} 
+{$include NSSegmentedControl.inc} 
+{$include NSSlider.inc} 
+{$include NSTextField.inc} 
+{$include NSTokenField.inc} 
+{$include NSWindow.inc}
+{$include NSPanel.inc} 
+{$include NSColorPanel.inc} 
+{$include NSFontPanel.inc}
+{$include NSPrintPanel.inc} 
+{$include NSSavePanel.inc} 
+{$include NSOpenPanel.inc} 
+{$include NSWindowController.inc} 
+{$include NSWorkspace.inc} 
+{$include NSComboBox.inc} 
+{$include NSComboBoxCell.inc} 
+{$include NSTableColumn.inc} 
+{$include NSTableHeaderCell.inc} 
+{$include NSTableHeaderView.inc} 
+{$include NSTableView.inc} 
+{$include NSOutlineView.inc} 
+{$include NSAttributedString.inc} 
+{$include NSLayoutManager.inc} 
+{$include NSTextStorage.inc} 
+{$include NSTextView.inc} 
+{$include NSTextContainer.inc} 
+{$include NSTextAttachment.inc} 
+{$include NSInputManager.inc} 
+{$include NSInputServer.inc} 
+{$include NSStringDrawing.inc} 
+{$include NSRulerMarker.inc} 
+{$include NSRulerView.inc} 
+{$include NSSecureTextField.inc} 
+{$include NSInterfaceStyle.inc} 
+{$include NSProgressIndicator.inc} 
+{$include NSTabView.inc} 
+{$include NSTabViewItem.inc} 
+{$include NSMenuView.inc} 
+{$include NSMenuItemCell.inc} 
+{$include NSPopUpButtonCell.inc} 
+{$include NSAffineTransform.inc} 
+{$include NSBezierPath.inc} 
+{$include NSPICTImageRep.inc} 
+{$include NSStatusBar.inc} 
+{$include NSStatusItem.inc} 
+{$include NSSound.inc} 
+{$include NSMovie.inc} 
+{$include NSMovieView.inc} 
+{$include NSPDFImageRep.inc} 
+{$include NSQuickDrawView.inc} 
+{$include NSDrawer.inc} 
+{$include NSOpenGL.inc} 
+{$include NSOpenGLView.inc} 
+{$include NSApplicationScripting.inc} 
+{$include NSDocumentScripting.inc} 
+{$include NSTextStorageScripting.inc} 
+{$include NSToolbar.inc} 
+{$include NSToolbarItem.inc} 
+{$include NSToolbarItemGroup.inc} 
+{$include NSWindowScripting.inc} 
+{$include NSStepper.inc} 
+{$include NSStepperCell.inc} 
+{$include NSGlyphInfo.inc} 
+{$include NSShadow.inc} 
+{$include NSTypesetter.inc}
+{$include NSATSTypesetter.inc} 
+{$include NSGlyphGenerator.inc} 
+{$include NSSearchField.inc} 
+{$include NSSearchFieldCell.inc} 
+{$include NSController.inc} 
+{$include NSObjectController.inc} 
+{$include NSArrayController.inc} 
+{$include NSDictionaryController.inc} 
+{$include NSTreeNode.inc} 
+{$include NSTreeController.inc} 
+{$include NSUserDefaultsController.inc} 
+{$include NSKeyValueBinding.inc} 
+{$include NSTextList.inc} 
+{$include NSTextTable.inc} 
+{$include NSDatePickerCell.inc} 
+{$include NSDatePicker.inc} 
+{$include NSLevelIndicatorCell.inc} 
+{$include NSLevelIndicator.inc} 
+{$include NSAnimation.inc} 
+{$include NSPersistentDocument.inc} 
+{$include NSRuleEditor.inc} 
+{$include NSPredicateEditor.inc} 
+{$include NSPredicateEditorRowTemplate.inc}
+{$include NSPathCell.inc} 
+{$include NSPathControl.inc} 
+{$include NSPathComponentCell.inc} 
+{$include NSCollectionView.inc} 
+{$include NSTextInputClient.inc} 
+
+{ === From OS 10.6 === }
+{include NSOpenGLLayer.inc}
+{$include NSPasteboardItem.inc}
+{$include NSRunningApplication.inc}
+{$include NSTextInputContext.inc}
+{$include NSTouch.inc}
+{$include NSUserInterfaceItemSearching.inc}
+
+{ === Added for 10.6 parse but from 10.5 === }
+{$include NSUserInterfaceValidation.inc}

+ 0 - 0
packages/cocoaint/utils/cocoa-skel/src/appkit/CIColor.inc


+ 28 - 0
packages/cocoaint/utils/cocoa-skel/src/coredata/CoreData.inc

@@ -0,0 +1,28 @@
+{ Parsed from Coredata.framework CoreData.h }
+
+{ include CoreData.inc}
+{$include CoreDataDefines.inc}
+{$include CoreDataErrors.inc}
+
+{$include NSPersistentStore.inc}
+
+{$include NSAtomicStore.inc}
+{$include NSAtomicStoreCacheNode.inc}
+{$include NSPropertyDescription.inc}
+{$include NSAttributeDescription.inc}
+{$include NSEntityDescription.inc}
+{$include NSEntityMapping.inc}
+{$include NSEntityMigrationPolicy.inc}
+{$include NSExpressionDescription.inc}
+{$include NSFetchRequest.inc}
+{$include NSFetchRequestExpression.inc}
+{$include NSFetchedPropertyDescription.inc}
+{$include NSManagedObject.inc}
+{$include NSManagedObjectContext.inc}
+{$include NSManagedObjectID.inc}
+{$include NSManagedObjectModel.inc}
+{$include NSMappingModel.inc}
+{$include NSMigrationManager.inc}
+{$include NSPersistentStoreCoordinator.inc}
+{$include NSPropertyMapping.inc}
+{$include NSRelationshipDescription.inc}

+ 131 - 0
packages/cocoaint/utils/cocoa-skel/src/foundation/Foundation.inc

@@ -0,0 +1,131 @@
+
+{ Parse category/protocol symbols from NSObject.h }
+{-parse NSObject.h}
+
+{ This unit adds categories and protocols to NSObject in objcbase.pp }
+{ //include NSObjectSupport.inc} 
+
+{ === From OS 10.5 === }
+{$include NSObjCRuntime.inc} 
+{$include NSInvocation.inc}
+{$include NSPointerFunctions.inc}
+{$include NSAffineTransform.inc} 
+{$include NSArray.inc} 
+{$include NSAttributedString.inc}
+{$include NSAutoreleasePool.inc} 
+{$include NSBundle.inc} 
+{$include NSCalendar.inc} 
+{$include NSCharacterSet.inc} 
+{$include NSClassDescription.inc} 
+{$include NSCoder.inc} 
+{$include NSArchiver.inc} 
+{$include NSConnection.inc} 
+{$include NSData.inc} 
+{$include NSDate.inc} 
+{$include NSCalendarDate.inc} 
+{$include NSDecimal.inc} 
+{$include NSDictionary.inc} 
+{$include NSDistributedLock.inc} 
+{$include NSEnumerator.inc} 
+{$include NSError.inc} 
+{$include NSException.inc} 
+{$include NSFileHandle.inc} 
+{$include NSFileManager.inc} 
+{$include NSFormatter.inc} 
+{$include NSDateFormatter.inc}
+{$include NSGarbageCollector.inc} 
+{$include NSSet.inc} 
+{$include NSScanner.inc} 
+{$include NSValue.inc} 
+{$include NSDecimalNumber.inc}
+{$include NSValueTransformer.inc} 
+{$include NSGeometry.inc} 
+{$include NSHashTable.inc} 
+{$include NSHFSFileTypes.inc} 
+{$include NSHost.inc} 
+{$include NSIndexPath.inc} 
+{$include NSIndexSet.inc} 
+{$include NSKeyValueCoding.inc} 
+{$include NSKeyValueObserving.inc} 
+{$include NSKeyedArchiver.inc} 
+{$include NSLocale.inc} 
+{$include NSLock.inc} 
+{$include NSMapTable.inc} 
+{$include NSMetadata.inc} 
+{$include NSMethodSignature.inc} 
+{$include NSNetServices.inc} 
+{$include NSNotification.inc} 
+{$include NSNotificationQueue.inc} 
+{$include NSDistributedNotificationCenter.inc} 
+{$include NSNull.inc} 
+{$include NSNumberFormatter.inc} 
+{$include NSOperation.inc} 
+{$include NSPointerArray.inc} 
+{$include NSPort.inc} 
+{$include NSPortCoder.inc} 
+{$include NSPortMessage.inc} 
+{$include NSPortNameServer.inc} 
+{$include NSProcessInfo.inc} 
+{$include NSPropertyList.inc} 
+{$include NSProxy.inc} 
+{$include NSProtocolChecker.inc} 
+{$include NSDistantObject.inc} 
+{$include NSRange.inc} 
+{$include NSRunLoop.inc} 
+{$include NSSortDescriptor.inc} 
+{$include NSSpellServer.inc} 
+{$include NSStream.inc} 
+{$include NSString.inc} 
+{$include NSPathUtilities.inc} 
+{$include NSTask.inc} 
+{$include NSThread.inc} 
+{$include NSTimeZone.inc} 
+{$include NSTimer.inc} 
+{$include NSUndoManager.inc} 
+{$include NSURL.inc} 
+{$include NSURLHandle.inc} 
+{$include NSUserDefaults.inc} 
+{$include NSXMLNode.inc} 
+{$include NSXMLDTD.inc} 
+{$include NSXMLDTDNode.inc} 
+{$include NSXMLDocument.inc} 
+{$include NSXMLElement.inc} 
+{$include NSXMLNodeOptions.inc} 
+{$include NSXMLParser.inc} 
+{ include NSZone.inc} 
+{$include NSExpression.inc} 
+{$include NSPredicate.inc} 
+{$include NSComparisonPredicate.inc} 
+{$include NSCompoundPredicate.inc} 
+{$include NSAppleEventDescriptor.inc} 
+{$include NSAppleEventManager.inc} 
+{$include NSAppleScript.inc} 
+{$include NSObjectScripting.inc} 
+{$include NSScriptClassDescription.inc} 
+{$include NSScriptCoercionHandler.inc} 
+{$include NSScriptCommand.inc} 
+{$include NSScriptCommandDescription.inc} 
+{$include NSScriptExecutionContext.inc} 
+{$include NSScriptKeyValueCoding.inc} 
+{$include NSScriptObjectSpecifiers.inc} 
+{$include NSScriptStandardSuiteCommands.inc} 
+{$include NSScriptSuiteRegistry.inc} 
+{$include NSScriptWhoseTests.inc} 
+{$include NSURLAuthenticationChallenge.inc} 
+{$include NSURLCredential.inc} 
+{$include NSURLCredentialStorage.inc} 
+{$include NSURLProtectionSpace.inc} 
+{$include NSURLCache.inc} 
+{$include NSURLConnection.inc} 
+{$include NSURLProtocol.inc} 
+{$include NSURLRequest.inc} 
+{$include NSURLResponse.inc} 
+{$include NSHTTPCookie.inc} 
+{$include NSHTTPCookieStorage.inc} 
+{$include NSURLDownload.inc} 
+{$include NSURLError.inc} 
+
+{ === From OS 10.6 === }
+{$include NSCache.inc}
+{$include NSOrthography.inc}
+{$include NSTextCheckingResult.inc}

+ 52 - 0
packages/cocoaint/utils/cocoa-skel/src/quartzcore/QuartzCore.inc

@@ -0,0 +1,52 @@
+{$include CAAnimation.inc}
+{$include CABase.inc}
+{$include CIFilter.inc}
+{$include CALayer.inc}
+{$include CACIFilterAdditions.inc}
+{$include CAConstraintLayoutManager.inc}
+{$include CAEmitterCell.inc}
+{$include CAEmitterLayer.inc}
+{$include CAGradientLayer.inc}
+{$include CAMediaTiming.inc}
+{$include CAMediaTimingFunction.inc}
+{$include CAOpenGLLayer.inc}
+{$include CARenderer.inc}
+{$include CAReplicatorLayer.inc}
+{$include CAScrollLayer.inc}
+{$include CAShapeLayer.inc}
+{$include CATextLayer.inc}
+{$include CATiledLayer.inc}
+{$include CATransaction.inc}
+{$include CATransform3D.inc}
+{$include CATransformLayer.inc}
+{$include CAValueFunction.inc}
+{$include CIColor.inc}
+{$include CIContext.inc}
+{$include CIFilterGenerator.inc}
+{$include CIFilterShape.inc}
+{$include CIImage.inc}
+{$include CIImageAccumulator.inc}
+{$include CIImageProvider.inc}
+{$include CIKernel.inc}
+{$include CIPlugIn.inc}
+{$include CIPlugInInterface.inc}
+{$include CIRAWFilter.inc}
+{$include CISampler.inc}
+{$include CIVector.inc}
+{$include CVBase.inc}
+{$include CVBuffer.inc}
+{$include CVDisplayLink.inc}
+{$include CVHostTime.inc}
+{$include CVImageBuffer.inc}
+{$include CVOpenGLBuffer.inc}
+{$include CVOpenGLBufferPool.inc}
+{$include CVOpenGLTexture.inc}
+{$include CVOpenGLTextureCache.inc}
+{$include CVPixelBuffer.inc}
+{$include CVPixelBufferPool.inc}
+{$include CVPixelFormatDescription.inc}
+{$include CVReturn.inc}
+{ include CoreAnimation.inc}
+{ include CoreImage.inc}
+{ include CoreVideo.inc}
+{ include QuartzCore.inc}

+ 10 - 0
packages/cocoaint/utils/cocoa-skel/src/webkit/UndefinedTypes.inc

@@ -0,0 +1,10 @@
+type
+ WebNSUInteger = culong;
+ WebNSInteger = clong;
+ 
+ 
+{ Missing }
+type
+ JSGlobalContextRef = pointer;
+ JSObjectRef = pointer;
+ DOMTimeStamp = culonglong;

+ 167 - 0
packages/cocoaint/utils/cocoa-skel/src/webkit/WebKit.inc

@@ -0,0 +1,167 @@
+{ Parsed from Webkit.framework WebKit.h }
+
+{$include WebScriptObject.inc}
+{$include DOMObject.inc}
+{$include DOMNode.inc}
+
+{$include DOMCharacterData.inc}
+{$include DOMText.inc}
+
+{$include DOMStyleSheet.inc}
+
+{$include CarbonUtils.inc}
+{$include DOM.inc}
+{$include DOMAbstractView.inc}
+{$include DOMAttr.inc}
+{$include DOMCDATASection.inc}
+{$include DOMCSS.inc}
+{$include DOMCSSRule.inc}
+{$include DOMCSSValue.inc}
+{$include DOMCSSCharsetRule.inc}
+{$include DOMCSSFontFaceRule.inc}
+{$include DOMCSSImportRule.inc}
+{$include DOMCSSMediaRule.inc}
+{$include DOMCSSPageRule.inc}
+{$include DOMCSSPrimitiveValue.inc}
+{$include DOMCSSRuleList.inc}
+{$include DOMCSSStyleDeclaration.inc}
+{$include DOMCSSStyleRule.inc}
+{$include DOMCSSStyleSheet.inc}
+{$include DOMCSSUnknownRule.inc}
+{$include DOMCSSValueList.inc}
+{$include DOMComment.inc}
+{$include DOMCore.inc}
+{$include DOMCounter.inc}
+{$include DOMDocument.inc}
+{$include DOMDocumentFragment.inc}
+{$include DOMDocumentType.inc}
+{$include DOMElement.inc}
+{$include DOMEntity.inc}
+{$include DOMEntityReference.inc}
+{$include DOMEvent.inc}
+{$include DOMEventException.inc}
+{$include DOMEventListener.inc}
+{$include DOMEventTarget.inc}
+{$include DOMEvents.inc}
+{$include DOMException.inc}
+{$include DOMFile.inc}
+{$include DOMFileList.inc}
+{$include DOMHTML.inc}
+{$include DOMHTMLElement.inc}
+{$include DOMHTMLAnchorElement.inc}
+{$include DOMHTMLAppletElement.inc}
+{$include DOMHTMLAreaElement.inc}
+{$include DOMHTMLBRElement.inc}
+{$include DOMHTMLBaseElement.inc}
+{$include DOMHTMLBaseFontElement.inc}
+{$include DOMHTMLBodyElement.inc}
+{$include DOMHTMLButtonElement.inc}
+{$include DOMHTMLCollection.inc}
+{$include DOMHTMLDListElement.inc}
+{$include DOMHTMLDirectoryElement.inc}
+{$include DOMHTMLDivElement.inc}
+{$include DOMHTMLDocument.inc}
+{$include DOMHTMLEmbedElement.inc}
+{$include DOMHTMLFieldSetElement.inc}
+{$include DOMHTMLFontElement.inc}
+{$include DOMHTMLFormElement.inc}
+{$include DOMHTMLFrameElement.inc}
+{$include DOMHTMLFrameSetElement.inc}
+{$include DOMHTMLHRElement.inc}
+{$include DOMHTMLHeadElement.inc}
+{$include DOMHTMLHeadingElement.inc}
+{$include DOMHTMLHtmlElement.inc}
+{$include DOMHTMLIFrameElement.inc}
+{$include DOMHTMLImageElement.inc}
+{$include DOMHTMLInputElement.inc}
+{$include DOMHTMLIsIndexElement.inc}
+{$include DOMHTMLLIElement.inc}
+{$include DOMHTMLLabelElement.inc}
+{$include DOMHTMLLegendElement.inc}
+{$include DOMHTMLLinkElement.inc}
+{$include DOMHTMLMapElement.inc}
+{$include DOMHTMLMarqueeElement.inc}
+{$include DOMHTMLMenuElement.inc}
+{$include DOMHTMLMetaElement.inc}
+{$include DOMHTMLModElement.inc}
+{$include DOMHTMLOListElement.inc}
+{$include DOMHTMLObjectElement.inc}
+{$include DOMHTMLOptGroupElement.inc}
+{$include DOMHTMLOptionElement.inc}
+{$include DOMHTMLOptionsCollection.inc}
+{$include DOMHTMLParagraphElement.inc}
+{$include DOMHTMLParamElement.inc}
+{$include DOMHTMLPreElement.inc}
+{$include DOMHTMLQuoteElement.inc}
+{$include DOMHTMLScriptElement.inc}
+{$include DOMHTMLSelectElement.inc}
+{$include DOMHTMLStyleElement.inc}
+{$include DOMHTMLTableCaptionElement.inc}
+{$include DOMHTMLTableCellElement.inc}
+{$include DOMHTMLTableColElement.inc}
+{$include DOMHTMLTableElement.inc}
+{$include DOMHTMLTableRowElement.inc}
+{$include DOMHTMLTableSectionElement.inc}
+{$include DOMHTMLTextAreaElement.inc}
+{$include DOMHTMLTitleElement.inc}
+{$include DOMHTMLUListElement.inc}
+{$include DOMImplementation.inc}
+{$include DOMUIEvent.inc}
+{$include DOMKeyboardEvent.inc}
+{$include DOMMediaList.inc}
+{$include DOMMouseEvent.inc}
+{$include DOMMutationEvent.inc}
+{$include DOMNamedNodeMap.inc}
+{$include DOMNodeFilter.inc}
+{$include DOMNodeIterator.inc}
+{$include DOMNodeList.inc}
+{$include DOMNotation.inc}
+{$include DOMOverflowEvent.inc}
+{$include DOMProcessingInstruction.inc}
+{$include DOMProgressEvent.inc}
+{$include DOMRGBColor.inc}
+{$include DOMRange.inc}
+{$include DOMRangeException.inc}
+{$include DOMRanges.inc}
+{$include DOMRect.inc}
+{$include DOMStyleSheetList.inc}
+{$include DOMStylesheets.inc}
+{$include DOMTraversal.inc}
+{$include DOMTreeWalker.inc}
+{$include DOMViews.inc}
+{$include DOMWheelEvent.inc}
+{$include DOMXPath.inc}
+{$include DOMXPathException.inc}
+{$include DOMXPathExpression.inc}
+{$include DOMXPathNSResolver.inc}
+{$include DOMXPathResult.inc}
+{$include HIWebView.inc}
+{$include WebArchive.inc}
+{$include WebBackForwardList.inc}
+{$include WebDOMOperations.inc}
+{$include WebDataSource.inc}
+{$include WebDocument.inc}
+{$include WebDownload.inc}
+{$include WebEditingDelegate.inc}
+{$include WebFrame.inc}
+{$include WebFrameLoadDelegate.inc}
+{$include WebFrameView.inc}
+{$include WebHistory.inc}
+{$include WebHistoryItem.inc}
+{ include WebJavaPlugIn.inc}
+{ include WebKit.inc}
+{$include WebKitErrors.inc}
+{$include WebPlugin.inc}
+{$include WebPluginContainer.inc}
+{$include WebPluginViewFactory.inc}
+{$include WebPolicyDelegate.inc}
+{$include WebPreferences.inc}
+{$include WebResource.inc}
+{$include WebResourceLoadDelegate.inc}
+{$include WebUIDelegate.inc}
+{$include WebView.inc}
+{ include npapi.inc}
+{ include npfunctions.inc}
+{ include npruntime.inc}
+
+{$include DOMExtensions.inc}

+ 132 - 0
packages/cocoaint/utils/frameworks.xml

@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+	All frameworks that will be parsed must contain an entry in this file
+-->
+
+<frameworks>
+	
+	<framework>
+		<name>foundation</name>
+		<root>/foundation/Foundation.inc</root>
+		<bridge>/bridgesupport/foundation.xml</bridge>
+		<headers>/System/Library/Frameworks/Foundation.framework/Headers</headers>
+		<include_pattern>{[$]+include (.*).inc}</include_pattern>
+		<header_pattern>^(.*)\.h</header_pattern>
+		<!-- ignore_lines accepts regular expressions --> 
+		<ignore_lines>
+			<line>#define NS_BLOCKS_AVAILABLE [0-9]+</line>
+			<line>FOUNDATION_EXPORT void NSLog(NSString *format, ...) NS_FORMAT_FUNCTION(1,2);</line>
+			<line>FOUNDATION_EXPORT void NSLogv(NSString *format, va_list args) NS_FORMAT_FUNCTION(1,0);</line>
+			<line>FOUNDATION_EXPORT void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2)));</line>
+      <line>FOUNDATION_EXPORT void NSLogv(NSString *format, va_list args);</line>
+
+		</ignore_lines>
+		<ignore_comments>
+			<line>^[[:space:]]*NS.*\.h</line>
+			<line>MAC_OS_X_VERSION_MAX_ALLOWED</line>
+			<line>AVAILABLE_MAC_OS_X_VERSION</line>
+			<line>^[[:space:]]*Copyright[[:space:]]+(C)[[:space:]]+[0-9]+[[:space:]]+Apple Computer, Inc.</line>
+		</ignore_comments>
+	</framework>
+	
+	<framework>
+		<name>appkit</name>
+		<root>/appkit/AppKit.inc</root>
+		<bridge>/bridgesupport/appkit.xml</bridge>
+		<headers>/System/Library/Frameworks/AppKit.framework/Headers</headers>
+		<include_pattern>{[$]+include (.*).inc}</include_pattern>
+		<header_pattern>^(.*)\.h</header_pattern>
+		<ignore_comments>
+			<line>^[[:space:]]*NS.*\.h</line>
+			<line>MAC_OS_X_VERSION_MAX_ALLOWED</line>
+			<line>AVAILABLE_MAC_OS_X_VERSION</line>
+			<line>^[[:space:]]*Copyright[[:space:]]+(C)[[:space:]]+[0-9]+[[:space:]]+Apple Computer, Inc.</line>
+		</ignore_comments>
+	</framework>
+
+	<framework>
+		<name>uikit</name>
+		<root>/uikit/UIKit.inc</root>
+		<bridge></bridge>
+		<headers>/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.2.sdk/System/Library/Frameworks/UIKit.framework/Headers</headers>
+		<include_pattern>{[$]+include (UI.*).inc}</include_pattern>
+		<header_pattern>^UI(.*)\.h</header_pattern>
+		<external_macro>UIKIT_EXTERN</external_macro>
+	</framework>
+
+	<framework>
+		<name>opengles</name>
+		<root>/opengles/OpenGLES.inc</root>
+		<bridge></bridge>
+		<headers>/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.2.sdk/System/Library/Frameworks/OpenGLES.framework/Headers</headers>
+		<include_pattern>{[$]+include (EAGL.*).inc}</include_pattern>
+		<header_pattern>^EAGL(.*)\.h</header_pattern>
+		<external_macro>EAGL_EXTERN_CLASS</external_macro>
+	</framework>
+
+	<framework>
+		<name>webkit</name>
+		<root>/webkit/WebKit.inc</root>
+		<bridge>/bridgesupport/webkit.xml</bridge>
+		<headers>/System/Library/Frameworks/WebKit.framework/Headers</headers>
+		<include_pattern>{[$]+include (.*).inc}</include_pattern>
+		<header_pattern>^(.*)\.h</header_pattern>
+		<ignore_comments>
+			<line>^[[:space:]]*(DOM|Web).*\.h</line>
+			<line>^[[:space:]]*Copyright[[:space:]]+(C)[[:space:]]+[0-9]+[[:space:]]+Apple Computer, Inc.</line>
+		</ignore_comments>
+	</framework>
+	
+	<framework>
+		<name>coredata</name>
+		<root>/coredata/CoreData.inc</root>
+		<headers>/System/Library/Frameworks/CoreData.framework/Headers</headers>
+		<include_pattern>{[$]+include (.*).inc}</include_pattern>
+		<header_pattern>^(.*)\.h</header_pattern>
+		<external_macro>COREDATA_EXTERN</external_macro>
+	</framework>
+	
+	<framework>
+		<name>calendarstore</name>
+		<root>/calendarstore/CalendarStore.inc</root>
+		<headers>/System/Library/Frameworks/CalendarStore.framework/Versions/A/Headers</headers>
+		<include_pattern>{[$]+include (.*).inc}</include_pattern>
+		<header_pattern>^(.*)\.h</header_pattern>
+	</framework>
+	
+	<framework>
+		<name>quicklook</name>
+		<root>/quicklook/QuickLook.inc</root>
+		<headers>/System/Library/Frameworks/QuickLook.framework/Versions/A/Headers</headers>
+		<include_pattern>{[$]+include (.*).inc}</include_pattern>
+		<header_pattern>^(.*)\.h</header_pattern>
+		<external_macro>QL_EXPORT</external_macro>
+	</framework>
+	
+	<framework>
+		<name>quicklookui</name>
+		<root>/quicklookui/QuickLookUI.inc</root>
+		<headers>/System/Library/Frameworks/Quartz.framework/Versions/A/Frameworks/QuickLookUI.framework/Versions/A/Headers</headers>
+		<include_pattern>{[$]+include (.*).inc}</include_pattern>
+		<header_pattern>^(.*)\.h</header_pattern>
+		<external_macro>QL_EXPORT</external_macro>
+	</framework>
+
+	<framework>
+		<name>quartzcore</name>
+		<root>/quartzcore/QuartzCore.inc</root>
+		<headers>/System/Library/Frameworks/QuartzCore.framework/Headers</headers>
+		<include_pattern>{[$]+include (.*).inc}</include_pattern>
+		<header_pattern>^(.*)\.h</header_pattern>
+		<!-- Seperate with | (no spaces, regex is accepted) -->
+		<external_macro>CA_EXTERN</external_macro>
+		<!-- No spaces! -->
+		<ignore_types>SomeQuartzPointer,AnotherQuartzPointer</ignore_types>
+		<!-- Ignore these methods (Pascal names, no spaces) -->
+		<ignore_methods>render_toIOSurface_bounds_colorSpace,reclaimResources</ignore_methods>
+		<replace_types>
+		</replace_types>
+	</framework>
+	
+	
+</frameworks>

+ 30 - 0
packages/cocoaint/utils/make-cocoa-headers.sh

@@ -0,0 +1,30 @@
+#!/bin/bash
+
+# halt on error
+set -e
+
+# convert basic cocoa headers
+php parser.php -cocoa -root=`pwd`/cocoa-skel/src
+# convert webkit headers
+php parser.php -objp -all -frameworks=foundation,webkit -root=`pwd`/cocoa-skel/src
+# convert coredata headers
+php parser.php -objp -all -frameworks=foundation,coredata -root=`pwd`/cocoa-skel/src
+# correct some translations the automatic translation cannot handle
+patch -p0 < patches/cocoa-coredata-webkit.patch
+# empty two headers that exist both in foundation and in appkit, and that
+# thereby cause "duplicate identifier" errors
+echo > `pwd`/cocoa-skel/src/foundation/NSAttributedString.inc
+echo > `pwd`/cocoa-skel/src/foundation/NSAffineTransform.inc
+echo
+echo The headers have been converted and placed under
+echo `pwd`/cocoa-skel/src.
+echo If you wish to compile them, execute the following commands:
+echo cp ../Makefile cocoa-skel
+echo cd cocoa-skel
+echo make OPT="-O2 -ap"
+echo
+echo The compiled files can be installed afterwards using \"make install\"
+echo if required. If another compiler binary than the default one has to
+echo be used, specify the alternative compiler binary location in the
+echo last command by adding FPC=/full/path/to/ppcbinary
+echo

+ 43 - 0
packages/cocoaint/utils/make-ios-headers.sh

@@ -0,0 +1,43 @@
+#!/bin/bash
+
+# halt on error
+set -e
+
+# change
+SDKBASEPATH=/Developer/Platforms/iPhoneOS.Platform/Developer/SDKs/iPhoneOS3.2.sdk
+
+if [ $? -ne 0 ]; then
+  SDKBASEPATH="$1"
+fi;
+
+if [ ! -d "$SDKBASEPATH" ]; then
+  echo iOS SDK base path \"$SDKBASEPATH\"
+  echo not found, specify it as the first parameter to this script.
+  echo Note that this parser version has only been verified to work with the
+  echo iOS SDK 3.2
+  echo
+  exit 1
+fi
+
+# convert uikit and related framework headers
+php parser.php -objp -all -frameworks=foundation,quartzcore,opengles,uikit -root=`pwd`/uikit-skel/src -framework_path="$SDKBASEPATH"/System/Library/Frameworks
+# correct some translations the automatic translation cannot handle
+patch -p0 < patches/uikit.patch
+# rename badly named unit and include file
+sed -e 's/AnonClassDefinitionsQuartzcore/AnonClassDefinitionsUikit/' < uikit-skel/src/AnonClassDefinitionsQuartzcore.pas > uikit-skel/src/AnonClassDefinitionsUikit.pas
+mv uikit-skel/src/quartzcore/AnonIncludeClassDefinitionsQuartzcore.inc uikit-skel/src/uikit/AnonIncludeClassDefinitionsUikit.inc
+rm uikit-skel/src/AnonClassDefinitionsQuartzcore.pas
+# empty two include files that are part of the RTL objcbase unit
+echo > uikit-skel/src/foundation/NSObject.inc
+echo > uikit-skel/src/foundation/NSZone.inc
+
+echo
+echo The headers have been converted and placed under
+echo `pwd`/uikit-skel/src.
+echo If you wish to compile them, execute the following commands:
+echo cd uikit-skel/src
+echo ppcarm -XR$SDKBASEPATH -FD`echo $SDKBASEPATH|sed -e 's+/SDKs/[^/]*sdk$++'`/usr/bin -O2 -ap -Cfvfpv2 iPhoneAll.pas
+echo
+echo The compiled files can be installed afterwards by copying iPhoneAll.{o,ppu} and
+echo AnonClassDefinitionsUikit.{o,ppu} to a directory in your FPC unit path.
+echo

+ 56 - 105
packages/cocoaint/utils/parser.php

@@ -1,18 +1,20 @@
 <?php
 
-$version = "FrameworkParser: 1.3. PasCocoa 0.3, Objective-P 0.4";
+$version = "2.1.2";
 
-require("pascocoa_parser.php");
-require("objp_parser.php");
+require("source/pascocoa_parser.php");
+require("source/objp_parser.php");
 
 /**
- * Cocoa framework parser for PasCocoa
+ * Cocoa framework parser for Objective-Pascal
  * 
  * @author Ryan Joseph
+ * @author Jonas Maebe
  **/
 
 // These files have duplicates in AppKit and Foundation so we ignore the foundation versions and everything is merged into AppKit
-$duplicate_headers = array("foundation/NSAttributedString.inc", "foundation/NSAffineTransform.inc");
+# $duplicate_headers = array("foundation/NSAttributedString.inc", "foundation/NSAffineTransform.inc");
+$duplicate_headers = array();
 
 // Print only these files
 $only_files = null;
@@ -43,6 +45,7 @@ function HandleCommandLineOptions ($argv) {
 				$where = explode("/", trim($value, "\""));
 				$options[$key]["framework"] = ucfirst($where[0]);
 				$options[$key]["name"] = $where[1];
+				$options["all"] = false;	// headers override -all
 				break;
 				
 			case 'framework_path':
@@ -61,11 +64,15 @@ function HandleCommandLineOptions ($argv) {
 				$options[$key] = true;
 				break;
 
-			case 'delegates':
+			case 'noprint':
 				$options[$key] = true;
 				break;
-
-			case 'noprint':
+				
+			case 'comments':
+				$options[$key] = true;
+				break;
+				
+			case 'merge':
 				$options[$key] = true;
 				break;
 
@@ -112,15 +119,18 @@ function HandleCommandLineOptions ($argv) {
 $testing = false;
 
 if ($testing) {
-	$GLOBALS["argv"][] = "-webkit";
-	$GLOBALS["argv"][] = "-root=/Developer/ObjectivePascal";
-	$GLOBALS["argv"][] = "-delegates";
+	print("=== WARNING: TESTING MODE ENABLED - COMMAND LINE IS OVERRIDDEN! ===\n");
+	//$GLOBALS["argv"][] = "-webkit";
+	$GLOBALS["argv"][] = "-root=/Developer/ObjectivePascal/dev";
+	//$GLOBALS["argv"][] = "-delegates";
+	$GLOBALS["argv"][] = "-objp";
+	$GLOBALS["argv"][] = "-comments";
 	//$GLOBALS["argv"][] = "-reference";
-	//$GLOBALS["argv"][] = "-all";
-	$GLOBALS["argv"][] = "-noprint";
+	$GLOBALS["argv"][] = "-all";
+	//$GLOBALS["argv"][] = "-noprint";
 	//$GLOBALS["argv"][] = "-show";
 	//$GLOBALS["argv"][] = "-only=\"UIWindow.h\"";
-	//$GLOBALS["argv"][] = "-frameworks=\"appkit,foundation\"";
+	$GLOBALS["argv"][] = "-frameworks=\"^foundation,quartzcore,appkit\"";
 
 	//$GLOBALS["argv"][] = "-framework_path=\"/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.2.1.sdk/System/Library/Frameworks\"";
 	//$GLOBALS["argv"][] = "-header=\"uikit/UIView.h\"";
@@ -129,92 +139,33 @@ if ($testing) {
 	//$GLOBALS["argv"][] = "-header=\"webkit/DOMDocument.h\"";
 	
 	//$GLOBALS["argv"][] = "-framework_path=\"/System/Library/Frameworks\"";
-	//$GLOBALS["argv"][] = "-header=\"foundation/NSBundle.h\"";
-	//$GLOBALS["argv"][] = "-header=\"appkit/NSBundle.h\"";
-	
-	$GLOBALS["argv"][] = "-ignore=\"NSGeometry.h,NSRange.h\"";
-	$GLOBALS["argv"][] = "-objp";
+	//$GLOBALS["argv"][] = "-header=\"foundation/NSObjcRuntime.h\"";
+	//$GLOBALS["argv"][] = "-header=\"foundation/NSMapTable.h\"";
+	$GLOBALS["argv"][] = "-header=\"appkit/NSApplication.h\"";
+	//$GLOBALS["argv"][] = "-header=\"quartzcore/CALayer.h\""; //CAMediaTimingFunction
 
-	// Objective-P
-	/* Notes for master compile (-all):
-
-	• CocoaAll.pas:
-	
-		Compiling /Developer/ObjectivePascal/CocoaAll.pas
-		1) NSWorkspace.inc(35,46) Error: Duplicate identifier "NSWorkspaceLaunchAllowingClassicStartup"
-		2) NSClassDescription.inc(60,55) Error: Duplicate identifier "description"
-		3) NSScriptObjectSpecifiers.inc(194,44) Error: Duplicate identifier "classDescription"
-		4) NSScriptSuiteRegistry.inc(75,40) Error: Duplicate identifier "classDescription"
-		5) NSControl.inc(136,15) Error: Mismatch between number of declared parameters and number of colons in message string.
-		6) NSWorkspace.inc(135,189) Error: Duplicate identifier "description"
-		7) NSMenuItemCell.inc(64,9) Error: Duplicate identifier "reserved"
-		8) NSRuleEditor.inc(127,15) Error: Mismatch between number of declared parameters and number of colons in message string.
-		9) NSObjCRuntime.inc(79,24) Fatal: Syntax error, "identifier" expected but ":" found
-		Fatal: Compilation aborted	
-	
-		1) NSWorkspace.h has a duplicate NSWorkspaceLaunchAllowingClassicStartup constant
-		2) NSObjcRuntime.h contains a bad external function:
-			function __attribute__(: (format(__NSString__; : 1; : 2))): void NSLog(NSStringRef *format, ...); cdecl; external name '__attribute__';
-			procedure NSLog(fmt:NSString); cdecl; varargs; external;
-		3) NSMenuItemCell.h has a duplicate (case sensitive name not allowed in Pascal) field that must be changed by hand.
-		4) These methods have problems in the params. This is a Objc convention where an absent type is always "id"
-			- (void)performClick:sender;
-			- (void)setDelegate:delegate;
-			NSControl.inc(136,15) Error: Mismatch between number of declared parameters and number of colons in message string.
-			NSRuleEditor.inc(124,15) Error: Mismatch between number of declared parameters and number of colons in message string.
-		5) NSInteger types are wrong in NSObjcRuntime (should be long)
-		  NSInteger = clong;
-		  NSUInteger = culong;
-		  NSNotFound = high(NSInteger);
-	    6) Many description and classDescription identifiers are not protected in name space and cause errors
-
-	• iPhoneAll.pas
-		1) UIAccelerometer: FPC bug causes methods with a single character message to fail. Remove the 3 methods affected
-			UIAccelerometer.inc(67,49) Error: Illegal expression after message directive
-		2) There's no way to know that UITextInputTraits is actually UITextInputTraitsProtocol due to name changes for Pascal syntax
-			UITextField.inc(91,32) Error: Identifier not found "UITextInputTraits"
-	
-	• WebKit.pas
-		1) Extra duplicate type in DOMObject.inc
-			DOMObjectInternal = Pointer;
-		  	DOMObjectInternal = DOMObjectInternal;
-		  
-		2) DOMDocument has method with reserved keyword name "implementation"
-			function implementation: DOMImplementation; message 'implementation';
-		 
-		3) DOMEvent has method with reserved keyword name "type"   
-			function type: NSString; message 'type';
-		
-		* reserved keywords are not protected in method names. This is messing up WebKit parsing badly
-		
-	- General notes:
-	1) NSObject.h is parsed for the merged category methods that should be inserted manually into the real root class
-	2) NSRange.h was ignored because it contains custom code and can be maintained by hand very easily
-	3) NSGeometry.h was ignored because it contains many parsing errors and custom code, do this by hand for now.
-	4) All instance variables are placed into "private" for now. There are a very small number of classes that have public ivar's.
-	*/
-	
 	//$GLOBALS["argv"][] = "-show";
 }
 
 if (count($GLOBALS["argv"]) == 1) {
 	print("Cocoa Framework Parser ($version) usage:\n");
-	print("php parser.php [switches]\n\n");
-	print("switches:\n\n");
-	print("  -all           print all headers (.h) from AppKit/Foundation frameworks\n");
-	print("  -header=\"foundation/NSObject.h\"    prints a single header from system frameworks\n");
-	print("  -root          sets the root path of the pascocoa directory\n");
-	print("  -framework_path	sets the root path of the frameworks directory (defaults to /System/Library/Frameworks)\n");
-	print("  -show     	    prints output to screen instead of file\n");
-	print("  -ignore=\"NSObject.h,NSArray.h\"     ignores the list of headers during parsing (-all only, no spaces)\n");
-	print("  -only=\"NSObject.h,NSArray.h\"       only prints these files (-all only, no spaces)\n");
-	print("  -noprint       parses but does not print (-all only)\n");
-	print("  -encodings     prints Pascal type encoding glue for GenerateTypeEncodings.p (-all only)\n");
-	print("  -delegates     prints NSDelegateController.inc to foundation (-all only)\n");
-	print("  -objp     		prints classes in FPC Objective-P dialect\n");
-	print("  -iphone     	one-time parse for iPhone headers\n");
-	print("  -cocoa     	one-time parse for Cocoa (AppKit/Foundation) headers\n");
-	print("  -frameworks=\"appkit,foundation\"    list of supported frameworks to parse\n");
+	print("php parser.php [options]\n\n");
+	print("Options:\n\n");
+	print("  -all           	Print all headers (.h) from AppKit/Foundation frameworks.\n");
+	print("  -header=\"foundation/NSObject.h\"    Prints a single header from system frameworks (if specified) or direct path.\n");
+	print("  -root          	Sets the root path of the output directory.\n");
+	print("  -framework_path	Sets the root path of the frameworks directory (defaults to /System/Library/Frameworks).\n");
+	print("  -show     	    	Prints output to screen instead of file (mutually exclusive to -noprint).\n");
+	print("  -comments     		Parses comments.\n");
+	print("  -merge     		Headers are merged by difference (using diff/patch) instead of overwritten.\n");
+	print("  -ignore=\"NSObject.h,NSArray.h\"     Ignores the list of headers during parsing (-all only, no spaces).\n");
+	print("  -only=\"NSObject.h,NSArray.h\"       Only print these files (-all only, no spaces).\n");
+	print("  -noprint       	Parses but does not print (-all only).\n");
+	print("  -encodings    	 	Prints Pascal type encoding glue for GenerateTypeEncodings.p (-all only).\n");
+	print("  -objp     			Prints classes in FPC Objective Pascal dialect (obsolete).\n");
+	print("  -iphone     		One-time parse for iPhone headers.\n");
+	print("  -cocoa     		One-time parse for Cocoa (AppKit/Foundation) headers.\n");
+	print("  -frameworks=\"appkit,foundation\"    List of supported frameworks to parse.\n");
 	print("\n\n");
 }
 
@@ -238,35 +189,35 @@ if ($options["out"]) {
 if ($options["iphone"]) {
 	$options["all"] = true;
 	$options["objp"] = true;
-	$options["frameworks"] = array("uikit");
+	$options["frameworks"] = array("foundation","quartzcore","uikit");
 }
 
 // setup -cocoa options
 if ($options["cocoa"]) {
 	$options["all"] = true;
 	$options["objp"] = true;
-	$options["frameworks"] = array("appkit","foundation");
-	$ignore_headers = array("NSGeometry.h","NSRange.h");
+	$options["frameworks"] = array("appkit","foundation","quartzcore");
+	$ignore_headers = array();
 }
 
 if ($options["webkit"]) {
 	$options["all"] = true;
 	$options["objp"] = true;
-	$options["frameworks"] = array("webkit");
+	$options["frameworks"] = array("foundation","webkit");
 }
 
 // create the parser instance
-if ($options["objp"]) {
-	$parser = new TObjPParser ($root_path, "", $options["frameworks"], $options["show"]);
-} else {
-	$parser = new TPasCocoaParser ($root_path, "", $options["frameworks"], $options["show"]);
-}
+$parser = new TObjPParser ($root_path, "", $options["frameworks"],  $options["framework_path"], $options["show"]);
+
+// Set additional options
+$parser->parse_comments = $options["comments"];
+$parser->merge_headers = $options["merge"];
 
 // Process single headers
 if ($options["header"] && !$options["all"]) {
 	$path = $options["framework_path"]."/".$options["header"]["framework"].".framework/Headers/".$options["header"]["name"];
 	print("* Processing $path...\n");
-	$parser->ProcessFile($path, true);
+	$parser->ProcessFile($path, !$options["noprint"]);
 }
 
 //$parser->PrintIvarSizeComparison("/Users/ryanjoseph/Desktop/objp/IvarSize.p");
@@ -274,7 +225,7 @@ if ($options["header"] && !$options["all"]) {
 
 // Process all headers
 if ($options["all"]) {
-	$parser->ParseCocoaFrameworks($ignore_headers, null);
+	$parser->ParseAllFrameworks($ignore_headers, null);
 	if (!$options["noprint"]) $parser->PrintAllHeaders("", $duplicate_headers, $only_files, $options["reference"]);
 	if ($options["delegates"]) $parser->ParseDelegateClasses();
 	if ($options["encodings"]) $parser->PrintTypeEncodingGlue();

+ 0 - 4163
packages/cocoaint/utils/pascocoa_parser.php

@@ -1,4163 +0,0 @@
-<?php
-function ReadTextFile ($path) {
-	if ($handle = fopen($path, "r")) {
-		return fread($handle, 400 * 1024);
-		fclose($handle);
-	}
-}
-	
-function str_replace_word ($needle, $replacement, $haystack) {
-    $pattern = "/\b$needle\b/";
-    $haystack = preg_replace($pattern, $replacement, $haystack);
-    return $haystack;
-}
-
-function istr_replace_word ($needle, $replacement, $haystack) {
-    $pattern = "/\b$needle\b/i";
-    $haystack = preg_replace($pattern, $replacement, $haystack);
-    return $haystack;
-}
-
-define("CAST_HANDLE", true);
-define("DONT_CAST_HANDLE", false);
-
-define("ACCESS_HANDLE_DIRECT", 1);
-define("ACCESS_HANDLE_FUNCTION", 2);
-
-define("REGISTER_SEL", true);
-define("DONT_REGISTER_SEL", false);
-
-define("USE_HANDLE", true);
-define("DONT_USE_HANDLE", false);
-	
-class TPasCocoaParser {
-
-	// Frameworks to parse
-	var $frameworks = array(	"foundation" => array(	"root" => "/foundation/Foundation.inc", 
-															"bridge" => "/bridgesupport/foundation.xml",
-															"headers" => "/System/Library/Frameworks/Foundation.framework/Headers",
-															"include_pattern" => "{[$]+include (NS.*).inc}",
-															"header_pattern" => "^NS(.*)\.h",
-															"enabled" => false,
-														),
-	
-								"appkit" => array(		"root" => "/appkit/AppKit.inc", 
-														"bridge" => "/bridgesupport/appkit.xml",
-														"headers" => "/System/Library/Frameworks/AppKit.framework/Headers",
-														"include_pattern" => "{[$]+include (NS.*).inc}",
-														"header_pattern" => "^NS(.*)\.h",
-														"enabled" => false,
-														),
-								
-								"uikit" => array(		"root" => "/uikit/UIKit.inc", 
-														"bridge" => "/bridgesupport/appkit.xml",
-														//"headers" => "/Users/ryanjoseph/Desktop/iphone/UIKit.framework/Headers",
-														"headers" => "/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.2.1.sdk/System/Library/Frameworks/UIKit.framework/Headers",
-														"include_pattern" => "{[$]+include (UI.*).inc}",
-														"header_pattern" => "^UI(.*)\.h",
-														"enabled" => false,
-														),
-								
-								"webkit" => array(		"root" => "/webkit/WebKit.inc", 
-														"bridge" => "/bridgesupport/webkit.xml",
-														"headers" => "/System/Library/Frameworks/WebKit.framework/Headers",
-														"include_pattern" => "{[$]+include (.*).inc}",
-														"header_pattern" => "^(.*)\.h",
-														"enabled" => false,
-														),
-														
-								"coredata" => array(	"root" => "/coredata/CoreData.inc", 
-														"bridge" => "/bridgesupport/coredata.xml",
-														"headers" => "/Developer/SDKs/MacOSX10.5.sdk/System/Library/Frameworks/CoreData.framework/Headers",
-														"include_pattern" => "{[$]+include (.*).inc}",
-														"header_pattern" => "^(.*)\.h",
-														"enabled" => false,
-														),
-								);
-	
-	var $maximum_method_length = 111; 	// WE GET THIS ERROR: NSDelegatesAll.pas(6109,296) Error: Identifier not found "NSDelegateController_NSLayoutManagerDelegate_layoutManager_shouldUseTemporaryAttributes_forDrawingToScreen_atCharacterIndex_effectiveRange"
-	
-	var $output;									// current output file handle                        
-	var $root;										// root for printing/locating resources              
-	var $out;										// directory to print                                
-	var $show;										// print output to screen instead of file            
-	var $framework;									// current framework being parsed                    
-	var $current_class;								// reference to current class structure being parsed 
-	var $current_header;							// reference to current header structure being parsed
-	var $method_count;								// count of all methods parsed                       
-	var $class_count;								// count of all classes parsed                       
-	var $warning_count;								// count of parser warnings                          
-	var $parser_skipping;							// the parser is skipping lines in the current file  
-	var $inside_macro_block;						// the parser is inside a macro block, no nesting!
-	var $instance_var_scope;						// current scope of the instance variable parser
-	var $cocoa_classes = array(); 					// array of all NS*** classes                        
-	var $cocoa_categories = array(); 				// array of all NS*** categories	                 
-	var $dump = array();							// Convert Pascal classes
-	var $delegate_methods = array();				// Delegate methods and types from GEN_BRIDGE_METADATA XML data
-	var $delegate_method_names = array();			// Delegate method name array
-	var $type_encodings = array();					// Master listing of type encodings for each method in the frameworks
-	
-	/**
-	 * PARSER OPTIONS
-	 */
-	var $objc_id = "NSObjectRef";							// Default type for generic objects
-	var $objc_id_real = "NSObjectRef";						// The real type of generic objects (id)
-	var $objc_id_base = "Pointer";							// The base type for all "Ref" types
-	var $sel_string = "SELString";							// The selector string type which registers selectors internally
-	var $protocol_suffix = "Protocol";						// All protocols append this suffix 
-	var $pointer_type_suffx = "Ref";						// NS*** pointers in parameter lists are suffixed with this
-	var $class_pointer_suffix = "Pointer";					// Pointers to NS*** classes are suffxed with this
-	var $register_selectors = true;							// Register selectors automatically inside the wrappers
-	var $show_added_messages = false;						// show messages when methods are added to a class
-	var $show_class_hierarchy = false;
-	var $objects_are_wrappers = false;						// Treat all objects (id) like wrappers. i.e aObject.Handle;
-	var $replace_hinted_params = false;						// replace comment hints with hinted type - (void * /* CMProfileRef */)colorSyncProfile;
-	var $master_delegate_class = "NSDelegateController";	// Name of the master delegate class
-	var $master_delegate_file = "NSDelegatesAll";			// Name of the master delegate file (no extension)
-	var $trailing_underscore = false;						// Append the trailing underscore for last parameter
-	var $record_keyword = "record";							// The keyword used for printing records
-	var $bitpacked_record_keyword = "bitpacked record";		// The keyword used for printing bitpacked records
-	var $string_macro = "NSString";
-	
-	// Pascal keywords to protect
-	var $reserved_keywords = array(	"const", "object", "string", "array", "var", "set", "interface", "classname", "unit",
-									"self", "type", "raise", "property", "to", "for", "with", "function", "procedure", "result",
-									"pointer", "create", "new", "dispose", "label", "packed", "record", "char", "class",
-									);
-									
-	// FPC methods that can't be overloaded
-	var $reserved_methods = array("className");
-	
-	// Types which can not be altered by reserved keywords
-	var $reserved_types = array("Pointer");
-	
-	// Objective-c types to convert
-	var $replace_types = array(	"id"=>"NSObjectRef", "void"=>"Pointer", "BOOL"=>"LongBool", "long"=>"LongInt", "int"=>"Integer",
-								"unsigned long"=>"UInt32", "unsigned short"=>"UInt8", "void *"=>"Pointer", "unsigned int"=>"UInt16",
-								"NSUInteger"=>"UInt32", "NSInteger"=>"SInt32", "Class"=>"Pobjc_class", "uint"=>"UInt16", 
-								"uint8_t"=>"UInt8", "signed int"=>"Integer", "const char"=>"PChar", "const void"=>"Pointer",
-								"const uint8_t"=>"Pointer", "unsigned"=>"UInt8", "int32_t"=>"SInt32", "float"=>"Float32",
-								"unsigned long long"=>"UInt64", "int64_t"=>"SInt64", "uint32_t"=>"UInt32", "uint16_t"=>"UInt16",
-								"unsigned char"=>"char", "short"=>"SInt8", "double"=>"Float64", "long long"=>"SInt64",
-								
-								// macros
-								"IBAction"=>"void",
-															
-								// special pointers
-								"const id *"=>"NSObjectArrayOfObjectsPtr", "Protocol *"=>"ObjcProtocol", "NSObject *"=>"NSObjectRef",
-								"const char *"=>"PChar", "const void *"=>"Pointer", "unsigned char *"=>"Pointer", "char *"=>"Pointer",
-								"unsigned *"=>"Pointer",
-								);						
-	
-	// These "types" are hints to the Objective-C garbage collector
-	var $garbage_collector_hints = array("__strong", "__weak");
-
-	var $null_macros = array("IBOutlet", "IBAction");
-	
-	// External NSString macros. These should be moved into the frameworks array
-	var $external_string_macros = "APPKIT_EXTERN|FOUNDATION_EXPORT|UIKIT_EXTERN|COREDATA_EXTERN";
-
-	// Types which have known pointers declared in the headers
-	var $pointer_types = array(	// MacOSAll types
-								"CGFloat"=>"psingle", "UInt32"=>"UInt32Ptr", "SInt32"=>"SInt32Ptr",
-								
-								// Cocoa types
-								"BOOL"=>"pboolean",
-								
-								"unsigned char"=>"pchar", 
-								"unsigned short"=>"pcushort", "unsigned int"=>"pcuint",	"uint"=>"pcuint", "signed int"=>"pcint",
-								"float"=>"psingle", "double"=>"pdouble", "long long"=>"pclonglong","long"=>"pclong", "unsigned long"=>"pculong", 
-								"int"=>"pinteger","uint8_t"=>"pbyte","unsigned"=>"pbyte","unsigned long long"=>"pculonglong"
-								);
-
-	var $objc_object_array = "id; objParams: array of const"; // Type which represents a dynamic array of Objective-c objects (id)
-	
-	// Symbols to ignore
-	var $ignore_symbol = array("NSApp");
-	
-	// Categories to ignore
-	var $ignore_categories = array("NSCoderMethods", "NSDeprecatedKeyValueCoding", "NSDeprecated");
-	
-	// Methods to ignore
-	var $ignore_methods = array(	"retain", "release", "retainCount", "copyWithZone", "mutableCopyWithZone",
-									"allocWithZone", "alloc", "copy", "mutableCopy", "self_", "autorelease", "awakeFromNib",
-									"observationInfo",
-								);	
-	
-	// default protected keywords by class/category
-	// these may be useful if super classes were not parsed before
-	var $default_protected = array(	"*"=>array("description", "classDescription"),
-									"NSDeprecated"=>array("accessoryView"),
-									"NSToolbarSupport"=>array("toolbar"),
-									"DOMNode"=>array("version"),
-									"WebView"=>array("frame"),
-									"DOMImplementation"=>array("version"),
-									);
-	
-	// Send methods that have a custom design
-	var $custom_send_methods = array(	"NSArray.arrayWithObjects", "NSArray.initWithObjects", 
-										"NSDictionary.dictionaryWithObjectsAndKeys", "NSDictionary.initWithObjectsAndKeys", 
-										"NSSet.setWithObjects", "NSSet.initWithObjects", 
-										);
-	
-	var $toll_free_bridge = array(	
-									"NSString"=>"CFStringRef", "NSArray"=>"CFArrayRef", "NSMutableString"=>"CFMutableStringRef",
-									"NSData"=>"CFDataRef", "NSDictionary"=>"CFDictionaryRef", "NSSet"=>"CFSetRef", 
-									"NSMutableArray"=>"CFMutableArrayRef", "NSMutableCharacterSetRef"=>"CFMutableCharacterSetRef",
-									"NSMutableData"=>"CFMutableDataRef", "NSMutableDictionary"=>"CFMutableDictionaryRef",
-									"NSMutableSet"=>"CFMutableSetRef",  "NSNumber"=>"CFNumberRef", "NSURL"=>"CFURLRef", 
-									"NSError"=>"CFErrorRef", 
-									
-									/* The Cocoa versions of these API's are much better and not very common, should we replace them?
-									"NSOutputStream"=>"CFWriteStreamRef", "NSPasteboard"=>"PasteboardRef"
-									"NSInputStream"=>"CFReadStreamRef", "NSTimer"=>"CFRunLoopTimerRef",
-									"NSTimeZone"=>"CFTimeZoneRef", "NSCharacterSet"=>"CFCharacterSetRef",
-									"NSDate"=>"CFDateRef",
-									*/
-									);	
-	
-	// types that use objc_msgSend_stret on all architectures
-	var $struct_types = array(	"NSRect", "NSDecimal", "NSFastEnumerationState", "NSMapTableValueCallBacks",
-								"NSHashTableCallBacks", "NSMapTableKeyCallBacks", 
-								
-								// TEMPORARY PARSER HACKS
-								"aeDesc_",
-								);
-						
-	// structs that use objc_msgSend or objc_msgSend_stret depending on architecture
-	// "On Mac OS X Intel/i386, records whose size is 1, 2, 4 or 8 bytes are returned using registers"
-	var $struct_register_types = array(	"NSRange", "NSPoint", "NSSize", "NSAffineTransformStruct" );
-														
-	// Functions that return types will invoke objc_msgSend_fpret
-	// NOTE: we must also know the exact type so we can make the proper function pointer
-	var $float_types = array(	// C-types
-								"float", "long double", "double", 
-								
-								// Cocoa types
-								"NSTimeInterval",
-								
-								// Pascal types
-								"Float64", "Float32",
-								
-								// CarbonTypes
-								"CGFloat",
-								);
-	
-	var $skip_blocks = array(	"^#if __LP64__ \|\| NS_BUILD_32_LIKE_64"=>"^#(else|endif)+",
-								);
-								
-	var $macro_blocks = array(	"^#if (__LP64__)"=>"\$ifdef cpu64",
-								"^#if ![[:space:]]*(__LP64__)"=>"\$ifndef cpu64",
-								"^#ifdef __BIG_ENDIAN__"=>"\$ifdef fpc_big_endian",
-								//"^#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_[0-9]+_[0-9]+"=>"*",
-								);
-								
-	// these categories should be placed into NSObject
-	var $base_categories = array(		"NSArchiverCallback", "NSClassDescriptionPrimitives", "NSCoderMethods", "NSComparisonMethods", 
-										"NSDelayedPerforming", "NSDeprecatedKeyValueCoding", "NSDeprecatedKeyValueObservingCustomization",
-										"NSDistributedObjects", "NSErrorRecoveryAttempting", "NSKeyValueCoding", "NSPlaceholders",
-										"NSKeyValueObserverRegistration", "NSKeyValueObserving", "NSKeyValueObservingCustomization", 
-										"NSKeyedArchiverObjectSubstitution", "NSKeyedUnarchiverObjectSubstitution", "NSDeprecatedMethods", 
-										"NSScriptKeyValueCoding", "NSThreadPerformAdditions", "NSServicesRequests", "NSKeyValueBindingCreation",
-										"NSAccessibility", "NSAccessibilityAdditions",
-										);
-										
-										// These really don't feel like they should be in NSObject, removing until we know where to put them.
-										// Maybe a new class? NSCategories...
-										
-										// "NSURLClient", "NSScripting", "NSScriptClassDescription", "NSScriptObjectSpecifiers", 
-										// "NSScriptingComparisonMethods", "NSFontManagerResponderMethod", "NSMenuValidation",
-										// "NSColorPanelResponderMethod", "NSFontPanelValidationAdditions", "NSToolbarItemValidation",
-										// "NSDictionaryControllerKeyValuePair", "NSEditor", 
-	/**
-	 * COMMON REGULAR EXPRESIONS
-	 */
-	var $regex_objc_method_params = "^(-|\+)[[:space:]]*\((.*)\)[[:space:]]*([a-zA-Z0-9]+):(.*);";
-	var $regex_objc_method_no_params = "^(-|\+)[[:space:]]*\((.*)\)[[:space:]]*([a-zA-Z0-9]+);";
-	var $regex_objc_category = "^@interface ([a-zA-Z]+)[[:space:]]*\(([a-zA-Z]+)\)";
-	var $regex_objc_class = "^@interface ([a-zA-Z]+)[[:space:]]*:[[:space:]]*([a-zA-Z]+)[[:space:]]*(<(.*)>)*";
-	var $regex_objc_class_no_super = "^@interface ([a-zA-Z]+)[[:space:]]*<(.*)>[[:space:]]*";
-	var $regex_objc_protocol = "^@protocol ([a-zA-Z]+)";
-	var $regex_procedure_type = "^[[:space:]]*(void|IBAction)+[[:space:]]*$";
-	var $regex_scope_compiler_directive = "^\s*@(private|protected|public)(;*)+\s*$";
-	var $regex_objc_property = "^@property\((.*)\)[[:space:]]*(.*);";
-	
-	/**
-	 * TEMPLATES
-	 */
-	
-	// Template for implemented function
-	var $template_implemented_function = "function [CLASS].implemented_[NAME][PARAMS_HEADER]: [RETURN];
-begin
-  {\$ifdef NSOBJECT_AUTO_WRAPPER}
-    Result :=  [RETURN](super_[NAME][PARAMS_BODY_WRAPPER]);
-  {\$else}
-    Result :=  [RETURN](super_[NAME][PARAMS_BODY]);
-  {\$endif}
-end;";
-
-	// Template for implemented procedure
-	var $template_implemented_procedure = "procedure [CLASS].implemented_[NAME][PARAMS_HEADER];
-begin
-  {\$ifdef NSOBJECT_AUTO_WRAPPER}
-    super_[NAME][PARAMS_BODY_WRAPPER];
-  {\$else}
-    super_[NAME][PARAMS_BODY];
-  {\$endif}
-end;";
-	
-	// Template for constructor
-	var $template_constructor = "constructor [CLASS][NAME][PARAMS_HEADER];
-type
-  TmsgSendWrapper = function (param1: id; param2: SEL[PARAMS_PROC]): id; cdecl;
-var
-  vmethod: TmsgSendWrapper;
-begin
-  if SEL_[SELNAME] = nil then
-    SEL_[SELNAME] := sel_registerName(PChar('[OBJC_METHOD]'));
-
-  RegisterSubClass;
-  allocbuf := objc_msgSend(ClassID, SEL_alloc, []);
-  vmethod := TmsgSendWrapper(@objc_msgSend);
-  Handle := vmethod(allocbuf, SEL_[SELNAME][PARAMS_LIST_WRAPPER]);
-  retainCount := 1;
-  AssignSelf(Handle);
-  AddMethods;
-  BindMethods;
-end;";	
-
-	// Template for constructor that does not allocate memory
-	var $template_constructor_no_alloc = "constructor [CLASS][NAME][PARAMS_HEADER];
-type
-  TmsgSendWrapper = function (param1: id; param2: SEL[PARAMS_PROC]): id; cdecl;
-var
-  vmethod: TmsgSendWrapper;
-begin
-  if SEL_[SELNAME] = nil then
-    SEL_[SELNAME] := sel_registerName(PChar('[OBJC_METHOD]'));
-
-  RegisterSubClass;
-  vmethod := TmsgSendWrapper(@objc_msgSend);
-  Handle := vmethod(ClassID, SEL_[SELNAME][PARAMS_LIST_WRAPPER]);
-  AutoReleaseObject;
-  AssignSelf(Handle);
-  AddMethods; 
-  BindMethods;
-end;";	
-
-	// Template for function to send Objective-c message that returns an auto-generated/memory managed wrapper object.
-	var $template_function_make_wrapper = "function [CLASS][NAME][PARAMS_HEADER]: [RETURN];
-type
-  TmsgSendWrapper = function (param1: id; param2: SEL[PARAMS_PROC]): [RETURN]; cdecl;
-var
-  vmethod: TmsgSendWrapper;
-  wrapper: [RETURN];
-begin
-  vmethod := TmsgSendWrapper(@[MSG_SEND]);
-  if SEL_[SELNAME] = nil then
-    SEL_[SELNAME] := sel_registerName(PChar('[OBJC_METHOD]'));
-
-  {\$ifdef NSOBJECT_AUTO_WRAPPER}
-    Result := [RETURN](vmethod([OBJC_OBJECT], SEL_[SELNAME][PARAMS_LIST_WRAPPER]));
-  {\$else}
-    Result := [RETURN](vmethod([OBJC_OBJECT], SEL_[SELNAME][PARAMS_LIST]));
-  {\$endif}
-
-  {\$ifdef NSOBJECT_AUTO_WRAPPER}
-   wrapper := [RETURN](GetWrapper(Result));
-   if wrapper = nil then
-     Result := [RETURN]([RETURN].CreateWithHandle(Pobjc_object(Result)).deferObject)
-   else
-     Result := wrapper;
-  {\$endif}
-end;";
-
-	var $template_function_make_wrapper_no_params = "function [CLASS][NAME]: [RETURN];
-var
-  wrapper: [RETURN];
-begin
-  if SEL_[SELNAME] = nil then
-	SEL_[SELNAME] := sel_registerName(PChar('[OBJC_METHOD]'));
-	
-  Result := [RETURN]([MSG_SEND]([OBJC_OBJECT], SEL_[SELNAME], []));
- 
- {\$ifdef NSOBJECT_AUTO_WRAPPER}
-  wrapper := [RETURN](GetWrapper(Result));
-  if wrapper = nil then
-    Result := [RETURN]([RETURN].CreateWithHandle(Pobjc_object(Result)).deferObject)
-  else
-    Result := wrapper;
- {\$endif}
-end;";
-
-	// Template for protocol function to send Objective-c message that returns an auto-generated/memory managed wrapper object.
-	var $template_protocol_make_wrapper = "function [CLASS][NAME][PARAMS_HEADER]: [RETURN];
-type
-  TmsgSendWrapper = function (param1: id; param2: SEL[PARAMS_PROC]): [RETURN]; cdecl;
-var
-  vmethod: TmsgSendWrapper;
-begin
-  vmethod := TmsgSendWrapper(@[MSG_SEND]);
-  if SEL_[SELNAME] = nil then
-	SEL_[SELNAME] := sel_registerName(PChar('[OBJC_METHOD]'));
-	
-  {\$ifdef NSOBJECT_AUTO_WRAPPER}
-    Result := [RETURN](vmethod([OBJC_OBJECT], SEL_[SELNAME][PARAMS_LIST_WRAPPER]));
-  {\$else}
-    Result := [RETURN](vmethod([OBJC_OBJECT], SEL_[SELNAME][PARAMS_LIST]));
-  {\$endif}
-
-  {\$ifdef NSOBJECT_AUTO_WRAPPER}
-   Result := [RETURN]([RETURN].CreateWithHandle(Pobjc_object(Result)).deferObject);
-  {\$endif}
-end;";
-
-	var $template_protocol_make_wrapper_no_params = "function [CLASS][NAME]: [RETURN];
-begin
-  if SEL_[SELNAME] = nil then
-    SEL_[SELNAME] := sel_registerName(PChar('[OBJC_METHOD]'));
-  Result := [RETURN]([MSG_SEND]([OBJC_OBJECT], SEL_[SELNAME], []));
-
- {\$ifdef NSOBJECT_AUTO_WRAPPER}
-   Result := [RETURN]([RETURN].CreateWithHandle(Pobjc_object(Result)).deferObject);
- {\$endif}
-end;";
-
-	// Template for function to send Objective-c message
-	var $template_function_objc_send = "function [CLASS][NAME][PARAMS_HEADER]: [RETURN];
-type
-  TmsgSendWrapper = function (param1: [TARGET_TYPE]; param2: SEL[PARAMS_PROC]): [RETURN]; cdecl;
-var
-  vmethod: TmsgSendWrapper;
-  super: objc_super;
-begin
-  vmethod := TmsgSendWrapper(@[MSG_SEND]);
-  if SEL_[SELNAME] = nil then
-    SEL_[SELNAME] := sel_registerName(PChar('[OBJC_METHOD]'));
-	
-  [GET_SUPER_CLASS]
-  {\$ifdef NSOBJECT_AUTO_WRAPPER}
-    Result := [RETURN](vmethod([OBJC_OBJECT], SEL_[SELNAME][PARAMS_LIST_WRAPPER]));
-  {\$else}
-    Result := [RETURN](vmethod([OBJC_OBJECT], SEL_[SELNAME][PARAMS_LIST]));
-  {\$endif}
-end;";
-
-	// Template for function to send Objective-c message (no params)
-	var $template_function_objc_send_no_params = "function [CLASS][NAME]: [RETURN];
-var
-  super: objc_super;
-begin
-  if SEL_[SELNAME] = nil then
-    SEL_[SELNAME] := sel_registerName(PChar('[OBJC_METHOD]'));
-  [GET_SUPER_CLASS]
-  Result := [RETURN]([MSG_SEND]([OBJC_OBJECT], SEL_[SELNAME], []));
-end;";
-	
-	// Template for function to send Objective-c message which returns a struct
-	var $template_function_objc_send_struct = "function [CLASS][NAME][PARAMS_HEADER]: [RETURN];
-type
-  TmsgSendWrapper = function (param1: [TARGET_TYPE]; param2: SEL[PARAMS_PROC]): [RETURN]; cdecl;
-var
-  vmethod: TmsgSendWrapper;
-  super: objc_super;
-begin
-  if SEL_[SELNAME] = nil then
-    SEL_[SELNAME] := sel_registerName(PChar('[OBJC_METHOD]'));
-  vmethod := TmsgSendWrapper(@[MSG_SEND]);
-  [GET_SUPER_CLASS]
-  {\$ifdef NSOBJECT_AUTO_WRAPPER}
-    Result := [RETURN](vmethod([OBJC_OBJECT], SEL_[SELNAME][PARAMS_LIST_WRAPPER]));
-  {\$else}
-    Result := [RETURN](vmethod([OBJC_OBJECT], SEL_[SELNAME][PARAMS_LIST]));
-  {\$endif}
-end;";
-
-	// Template for function to send Objective-c message which returns a struct
-	var $template_function_objc_send_struct_cpu = "function [CLASS][NAME][PARAMS_HEADER]: [RETURN];
-type
-  TmsgSendWrapper_reg = function (param1: [TARGET_TYPE]; param2: SEL[PARAMS_PROC]): [RETURN]; cdecl;
-  TmsgSendWrapper_stret = function (param1: [TARGET_TYPE]; param2: SEL[PARAMS_PROC]): [RETURN]; cdecl;
-var
-  vmethod_reg: TmsgSendWrapper_reg;
-  vmethod_stret: TmsgSendWrapper_stret;
-  super: objc_super;
-begin
-  if SEL_[SELNAME] = nil then
-    SEL_[SELNAME] := sel_registerName(PChar('[OBJC_METHOD]'));
-  [GET_SUPER_CLASS]
-  {\$ifdef CPUi386}
-    vmethod_reg := TmsgSendWrapper_reg(@[MSG_SEND_REGISTER]);
-	{\$ifdef NSOBJECT_AUTO_WRAPPER}
-      Result := vmethod_reg([OBJC_OBJECT], SEL_[SELNAME][PARAMS_LIST_WRAPPER]);
-    {\$else}
-      Result := vmethod_reg([OBJC_OBJECT], SEL_[SELNAME][PARAMS_LIST]);
-    {\$endif}
-  {\$else}
-    vmethod_stret := TmsgSendWrapper_stret(@[MSG_SEND_STRET]);
-    {\$ifdef NSOBJECT_AUTO_WRAPPER}
-      Result := [RETURN](vmethod_stret([OBJC_OBJECT], SEL_[SELNAME][PARAMS_LIST_WRAPPER]));
-    {\$else}
-      Result := [RETURN](vmethod_stret([OBJC_OBJECT], SEL_[SELNAME][PARAMS_LIST]));
-    {\$endif}
-  {\$endif}
-end;";
-
-	// Template for function to send Objective-c message (no params) which returns a struct
-	var $template_function_objc_send_no_params_struct = "function [CLASS][NAME]: [RETURN];
-var
-  super: objc_super;
-begin
-  if SEL_[SELNAME] = nil then
-    SEL_[SELNAME] := sel_registerName(PChar('[OBJC_METHOD]'));
-  [GET_SUPER_CLASS]
-  [MSG_SEND](@Result, [OBJC_OBJECT], SEL_[SELNAME], []);
-end;";
-
-	// Template for function to send Objective-c message (no params) which returns CPU dependent struct
-	var $template_function_objc_send_no_params_struct_cpu = "function [CLASS][NAME]: [RETURN];
-type
-  TmsgSendWrapper = function (param1: [TARGET_TYPE]; param2: SEL): [RETURN]; cdecl;
-var
-  vmethod: TmsgSendWrapper;
-  super: objc_super;
-begin
-  if SEL_[SELNAME] = nil then
-    SEL_[SELNAME] := sel_registerName(PChar('[OBJC_METHOD]'));
-  [GET_SUPER_CLASS]
-  {\$ifdef CPUi386}
-    vmethod := TmsgSendWrapper(@[MSG_SEND_REGISTER]);
-    Result := vmethod([OBJC_OBJECT], SEL_[SELNAME]                       );
-  {\$else}
-    [MSG_SEND_STRET](@Result, [OBJC_OBJECT], SEL_[SELNAME], []);
-  {\$endif}
-end;";
-
-	// Template for procedure to send Objective-c message
-	var $template_procedure_objc_send = "procedure [CLASS][NAME][PARAMS_HEADER];
-type
-  TmsgSendWrapper = procedure (param1: [TARGET_TYPE]; param2: SEL[PARAMS_PROC]); cdecl;
-var
-  vmethod: TmsgSendWrapper;
-  super: objc_super;
-begin
-  if SEL_[SELNAME] = nil then
-    SEL_[SELNAME] := sel_registerName(PChar('[OBJC_METHOD]'));
-  vmethod := TmsgSendWrapper(@[MSG_SEND]);
-  [GET_SUPER_CLASS]
-  {\$ifdef NSOBJECT_AUTO_WRAPPER}
-    vmethod([OBJC_OBJECT], SEL_[SELNAME][PARAMS_LIST_WRAPPER]);
-  {\$else}
-    vmethod([OBJC_OBJECT], SEL_[SELNAME][PARAMS_LIST]);
-  {\$endif}
-end;";
-
-	// Template for procedure to send Objective-c message
-	var $template_procedure_objc_send_no_params = "procedure [CLASS][NAME];
-var
-  super: objc_super;
-begin
-  if SEL_[SELNAME] = nil then
-    SEL_[SELNAME] := sel_registerName(PChar('[OBJC_METHOD]'));
-  [GET_SUPER_CLASS]
-  [MSG_SEND]([OBJC_OBJECT], SEL_[SELNAME], []);
-end;";
-
-	// Template for procedure to call implemented class method. This is the procedure which the Objectice-c methods are sent to
-	var $template_procedure_objc_wrapper = "procedure [CLASS]_[NAME](_self: id; _cmd: SEL[PARAMS_HEADER]); cdecl;
-var
-  this: [CLASS];
-  [VARIABLES]
-begin
-  this := [CLASS]([CLASS].GetSelf(_self));
-  if this <> nil then
-  {\$ifdef NSOBJECT_AUTO_WRAPPER}
-    begin
-      [WRAPPERS_CREATE]
-      this.implemented_[NAME][PARAMS_LIST_WRAPPER];
-      [WRAPPERS_RELEASE]
-    end;
-  {\$else}
-    this.implemented_[NAME][PARAMS_LIST];
-  {\$endif}
-end;";
-
-	// Template for procedure to call implemented class method. This is the procedure which the Objectice-c methods are sent to
-	var $template_function_objc_wrapper = "function [CLASS]_[NAME](_self: id; _cmd: SEL[PARAMS_HEADER]): [RETURN]; cdecl;
-var
-  this: [CLASS];
-  [VARIABLES]
-begin
-  this := [CLASS]([CLASS].GetSelf(_self));
-  if this <> nil then
-  {\$ifdef NSOBJECT_AUTO_WRAPPER}
-    begin
-      [WRAPPERS_CREATE]
-      Result := [RETURN](this.implemented_[NAME][PARAMS_LIST_WRAPPER]);
-      [WRAPPERS_RELEASE]
-    end;
-  {\$else}
-    Result := [RETURN](this.implemented_[NAME][PARAMS_LIST]);
-  {\$endif}
-end;";
-
-
-	// Template for method to override Objective-c method
-	var $template_method_override = "procedure [CLASS].override_[NAME];
-begin
-  AddMethod('[OBJC_METHOD]', '[TYPE_ENCODING]', Pointer(@[CLASS]_[NAME]));
-end;";
-
-	// Template for method to override Objective-c method
-	var $template_method_override_DEPRECATED = "procedure [CLASS].override_[NAME];
-begin
-  OverrideMethod('[OBJC_METHOD]', Pointer(@[CLASS]_[NAME]));
-end;";
-
-	// Template for method to add method to Objective-c runtime
-	var $template_method_add_runtime = "procedure [CLASS].add_[NAME];
-begin
-  AddMethod('[OBJC_METHOD]', '[TYPES]', Pointer(@[CLASS]_[NAME]));
-end;";
-
-	// Template for implemented delegate procedure
-	var $template_procedure_delegate = "procedure [CLASS].[NAME][PARAMS];
-begin
-end;";
-
-	// Template for implemented delegate procedure
-	var $template_function_delegate = "function [CLASS].[NAME][PARAMS]: [RETURN];
-begin
-end;";
-	
-	
-	// Template for implemented delegate procedure
-	var $template_procedure_delegate_objc = "procedure [CLASS]_[NAME][PARAMS_HEADER]; cdecl;
-var 
-  this: [CLASS];
-  [VARIABLES]
-begin
-  this := [CLASS]([CLASS].GetSelf(_self));
-  if this <> nil then
-  {\$ifdef NSOBJECT_AUTO_WRAPPER}
-    begin
-      [WRAPPERS_CREATE]
-      this.[NAME][PARAMS_LIST_WRAPPER];
-      [WRAPPERS_RELEASE]
-    end;
-  {\$else}
-    this.[NAME][PARAMS_LIST];
-  {\$endif}
-end;";
-
-	// Template for implemented delegate procedure
-	var $template_function_delegate_objc = "function [CLASS]_[NAME][PARAMS_HEADER]: [RETURN]; cdecl;
-var
-  this: [CLASS];
-  [VARIABLES]
-begin
-  this := [CLASS]([CLASS].GetSelf(_self));
-  if this <> nil then
-  {\$ifdef NSOBJECT_AUTO_WRAPPER}
-    begin
-      [WRAPPERS_CREATE]
-      Result := [RETURN](this.[NAME][PARAMS_LIST_WRAPPER]);
-      [WRAPPERS_RELEASE]
-    end;
-  {\$else}
-    Result := [RETURN](this.[NAME][PARAMS_LIST]);
-  {\$endif}
-end;";
-
-	// Template for create override in delegate class
-	var $template_delegate_create = "constructor [CLASS].Create;
-begin
-  CreateClassDefinition(ClassName, 'NSObject');
-
-  ClassID := objc_getClass('[CLASS]');
-  allocbuf := objc_msgSend(ClassId, SEL_alloc, []);
-  Handle := objc_msgSend(allocbuf, SEL_init, []);
-  retainCount := 1;
-
-  { Adds custom methods, if any }
-  AddMethods;
-  BindMethods;
-
-  { Assign our wrapper instance }
-  if Handle <> nil then
-    AssignSelf(Handle);
-end;";
-
-	// Template for constructor
-	var $template_constructor_constarray = "constructor [CLASS][NAME][PARAMS_HEADER];
-type
-  TmsgSendWrapper = function (param1: id; param2: SEL; param3: [CFTYPE]): id; cdecl;
-var
-  vmethod: TmsgSendWrapper;
-  paramList: [CFTYPE];
-  i: integer;
-begin
-  if SEL_[SELNAME] = nil then
-    SEL_[SELNAME] := sel_registerName(PChar('[OBJC_METHOD]'));
-  RegisterSubClass;
-  [ALLOC_PARAM_LIST]
-  allocbuf := objc_msgSend(ClassID, SEL_alloc, []);
-  vmethod := TmsgSendWrapper(@objc_msgSend);
-  Handle := vmethod(allocbuf, SEL_[SELNAME], paramList);
-  retainCount := 1;
-  AssignSelf(Handle);
-  AddMethods;
-  BindMethods;
-  CFRelease(paramList);
-end;";	
-
-	// Template for constructor that does not allocate memory
-	var $template_constructor_constarray_no_alloc = "constructor [CLASS][NAME][PARAMS_HEADER];
-type
-  TmsgSendWrapper = function (param1: id; param2: SEL; param3: [CFTYPE]): id; cdecl;
-var
-  vmethod: TmsgSendWrapper;
-  paramList: [CFTYPE];
-  i: integer;
-begin
-  if SEL_[SELNAME] = nil then
-    SEL_[SELNAME] := sel_registerName(PChar('[OBJC_METHOD]'));
-  RegisterSubClass;
-  [ALLOC_PARAM_LIST]
-  vmethod := TmsgSendWrapper(@objc_msgSend);
-  Handle := vmethod(ClassID, SEL_[SELNAME], paramList);
-  AutoReleaseObject;
-  AssignSelf(Handle);
-  AddMethods; 
-  BindMethods;
-  CFRelease(paramList);
-end;";	
-
-	// template to create param list for NSDictionary methods
-	var $template_dictionary_param_list = "paramList := CFDictionaryCreateMutable(nil, 0, @kCFTypeDictionaryKeyCallBacks, @kCFTypeDictionaryValueCallBacks);
-  i := High(firstObject);
-  while i > 0 do
-    begin
-      CFDictionaryAddValue(paramList, firstObject[i].VPointer, firstObject[i - 1].VPointer);
-      i := i - 2;
-    end;";
-
-	// template to create param list for NSArray methods
-	var $template_array_param_list = "paramList := CFArrayCreateMutable(nil, 0, @kCFTypeArrayCallBacks);
-  for i := 0 to High(firstObj) do
-    CFArrayAppendValue(paramList, firstObj[i].VPointer);";
-	
-	// template to create param list for NSSet methods
-	var $template_set_param_list = "paramList := CFSetCreateMutable(nil, 0, @kCFTypeSetCallBacks);
-  for i := 0 to High(firstObj) do
-    CFSetAddValue(paramList, firstObj[i].VPointer);";
-	
-	/**
-	 * UTILITIES
-	 */
-	
-	// Skips blocks in the current file being parsed
-	function SkipBlock ($line) {
-		
-		if ($line != "") {
-			foreach ($this->skip_blocks as $key => $value) {
-				if (@ereg($key, $line)) $this->parser_skipping = true;
-				if (@ereg($value, $line)) $this->parser_skipping = false;
-			}
-		}
-		
-		return $this->parser_skipping;
-	}
-	
-	function IsKeywordReserved($keyword) {
-		$keyword = strtolower($keyword);
-		if (in_array($keyword, $this->reserved_keywords)) return true;
-	}
-	
-	// Replace type with pointer equivalent
-	function ReplacePointerType ($type) {
-		
-		$type = "Pointer {".$type."}";
-		/*
-		foreach ($this->pointer_types as $objc_type => $replace_type) {
-			if ($objc_type == $type) {
-				$type = $replace_type;
-				break;
-			}
-		}
-		*/
-		return $type;
-	}
-	
-	// Makes a struct field into an inline array (or returns field un-changed)
-	function MakeFieldInlineArray ($io_field, $line, $name, $type) {
-
-		if (eregi("\[([0-9]+)\];", $line, $array_size)) {
-			$length = (int)$array_size[1] - 1;
-			if ($length > 0) {
-				$io_field = "    $name: array[0..$length] of $type;";
-			}
-		}
-		
-		return $io_field;
-	}
-
-	// Makes a type bitpacked (or returns type un-changed)
-	function MakeFieldBitPacked ($ioType, $field, &$bitpacked) {
-		$bitpacked = false;
-		
-		if (eregi(":([0-9]+);$", $field, $bitpack)) {
-			$length = (int)$bitpack[1];
-			if ($length > 1) {
-				$ioType = "0..((1 shl $length)-1)";
-			} else {
-				$ioType = "0..$length";
-			}
-			
-			$bitpacked = true;
-		}
-		
-		return $ioType;
-	}
-
-	// Replace objc type with preferred type
-	function ReplaceObjcType ($type) {
-		
-		foreach ($this->replace_types as $objc_type => $replace_type) {
-			if ($objc_type == $type) {
-				$type = $replace_type;
-				break;
-			}
-		}
-		
-		return $type;
-	}
-	
-	// Exchanges the preferred objc type with the real type
-	function SwapObjcTypeWithReal ($type) {
-		if ($type == $this->objc_id) $type = $this->objc_id_real;
-		
-		return $type;
-	}
-	
-	// Replace garbage collector hints
-	function ReplaceGarbageCollectorHints ($string, &$io_hint) {
-		$io_hint = false;
-		
-		foreach ($this->garbage_collector_hints as $hint) {
-			$out_string = str_ireplace($hint, "", $string);
-			if ($out_string != $string) {
-				$io_hint = $hint;
-				$string = $out_string;
-			}
-		}
-		
-		return $string;
-	}
-	
-	
-	// Replace type of reference parameter with pointer
-	function ReplaceReferenceParameterType ($type) {
-		foreach ($this->pointer_types as $key => $value) {
-			if ($key == $type) {
-				$found = true;
-				$type = $value;
-				break;
-			}
-		}
-		
-		if (!$found) $type = $type."Pointer";
-		
-		return $type;
-	}
-
-	// Replace NS*** "toll free bridge" types with CoreFoundation type
-	function ReplaceTollFreeBridgeType ($type) {
-		foreach ($this->toll_free_bridge as $objc_type => $replace_type) {
-			if ($objc_type == $type) {
-				$type = istr_replace_word($type, $replace_type, $type);
-				break;
-			}
-		}
-		
-		return $type;
-	}
-	
-	// Replace all NS*** classes in a string with the preffered generic type $this->objc_id
-	function ReplaceNSTypes ($string) {
-		foreach ($this->cocoa_classes as $class) {
-			$string = istr_replace_word($class, $this->objc_id, $string);
-		}
-		return $string;
-	}
-	
-	// Replace all NS*** classes in a string with id
-	function ReplaceNSTypesWithReal ($string) {
-		foreach ($this->cocoa_classes as $class) {
-			$string = istr_replace_word($class, $this->objc_id_real, $string);
-		}
-		return $string;
-	}
-	
-	// Replace all NS*** classes in a string with their reference equivalent (i.e NSStringRef = id)
-	function ReplaceNSTypesWithRef ($string) {
-		foreach ($this->cocoa_classes as $class) {
-			$string = istr_replace_word($class, $class."Ref", $string);
-		}
-		return $string;
-	}
-	
-	// Copies the name from an Objective-C method definition
-	function CopyObjcMethodName ($method) {
-		
-		// cut out comments first
-		$method = eregi_replace("(/\*.*\*/)", "", $method);
-		$method = eregi_replace("//.*$", "", $method);
-		$method = trim($method, " 	");
-		
-		$params = explode(":", $method);
-		$name = "";
-		
-		if (count($params) > 1) {
-			foreach ($params as $value) {
-				$value = trim($value, " 	");
-				if (eregi("([a-zA-Z0-9_]+)$", $value, $captures)) $name .= $captures[1].":";
-			}
-		} else {
-			if (eregi("([a-zA-Z0-9_]+)[[:space:]]*(;)*$", $method, $captures)) $name = $captures[1];
-		}
-		
-		return $name;
-	}
-	
-	// Converts a function pointer to Pascal function
-	function ConvertFunctionPointerToPascal ($result, $param_string) {
-		
-		if ($result != "") {
-			$params = explode(",", $param_string);
-			$function = "function (";
-			$count = 0;
-			
-			foreach ($params as $param) {
-				$count ++;
-				$param = trim($param, " ");
-				$param = $this->ReplaceObjcType($param);
-				$param = $this->SwapObjcTypeWithReal($param);
-				$param = trim($param, "*");
-				
-				$function .= "param$count: $param; ";
-			}
-			
-			$function = rtrim($function, "; ");
-			$function .= "): $result; cdecl;";
-		}
-		
-		//print("$function\n");
-		return $function;
-	}	
-	
-	// Converts a C parameter string to Pascal
-	function ConvertCParamsPascal ($string) {
-		
-		$params = explode(",", $string);
-		$param_string = "";
-		
-		foreach ($params as $param) {
-			
-			$param = istr_replace_word("const", "", $param);
-			$param = trim($param, " ");
-			
-			$pair = explode(" ", $param);
-			$name = $pair[1];
-			$type = $pair[0];
-				
-			$type = $this->ReplaceObjcType($type);
-			$type = $this->SwapObjcTypeWithReal($type);
-			$type = $this->ReplaceTollFreeBridgeType($type);
-			$type = $this->ReplaceNSTypesWithRef($type);
-			
-			if (($name[0] == "*") && ($name[1] == "*")) {
-				$name = trim($name, "*");
-				$type = $this->ReplacePointerType($type);
-			} elseif ($name[0] == "*") {
-				$name = trim($name, "*");
-				
-				$name = $name."Pointer";
-				//$name = "var $name";
-				
-				$name = trim($name, " ");
-			} else {
-				$name = trim($name, "*");
-			}
-			
-			// Remove array brackets (NSUInteger[])p
-			if (eregi("\[[0-9]*\]", $name)) {
-				$name = "$name";
-				$type = "Pointer {array of $type}";
-				$name = eregi_replace("\[[0-9]*\]", "", $name);
-			}
-  			
-			if ($this->IsKeywordReserved($name)) $name .= "_";
-			
-			// multiple parameters
-			if ($type == "...") {
-				$param_string .= "varargs: array of const";
-				break;
-			}
-			
-			$param_string .= "$name: $type; ";
-		}
-		
-		$param_string = trim($param_string, "; ");
-		return $param_string;
-	}
-	
-	// Remove OS X versions macros from a line
-	// NOTE: These should be re-inlcuded in Pascal
-	function RemoveOSVersionMacros ($line) {
-		$line = eregi_replace("[[:space:]]*AVAILABLE_MAC_OS_X_VERSION_[0-9]+_[0-9]+_AND_LATER[[:space:]]*", "", $line);
-		return $line;
-	}
-	
-	// Removes all comments from a line
-	function RemoveComments ($line) {
-		// remove single-line comments
-		$line = eregi_replace("[[:space:]]+//(.*)", "", $line);
-		
-		// remove multi-line comments /* ... */
-		$line = eregi_replace("/\*.*\*/", "", $line);
-		
-		return $line;
-	}
-	
-	// Performs additional formatting on Objective-c type i.e. (out NSObject **)
-	function FormatObjcType ($type, &$modifiers) {
-		$modifiers = "";
-		
-		// toss out all const identifiers
-		$type = istr_replace_word("const", "", $type);
-		
-		// replace inout paramaters
-		$type = istr_replace_word("inout", "", $type);
-		$type = istr_replace_word("out", "", $type);
-		$type_clean = trim($type, "* ");
-		
-		// Replace types before cleaning
-		$type = $this->ReplaceObjcType($type);
-		
-		// Remove protocol which type conforms to (id <NSURLHandleClient>)
-		$type = eregi_replace("<.*>", "", $type);
-		
-		// Remove array brackets (NSUInteger[])p
-		$type = eregi_replace("\[[0-9]*\]", "", $type);
-		
-		// var params to non-object types (NSRange *)
-		if (ereg("([a-zA-Z0-9_]+)[[:space:]]*[*]+$", $type, $captures)) { 
-			if ((!in_array($captures[1], $this->cocoa_classes)) && ($captures[1] != "id")) {
-				$type = $this->ReplaceReferenceParameterType($type_clean);	//"$type_clean$this->pointer_type_suffx";
-				//$modifiers = "var ";
-			}
-		} 
-		
-		// Handle NS*** pointers (NSError **)
-		if (ereg("(NS[a-zA-Z0-9_]+)[[:space:]]*\*\*$", $type, $captures)) { 
-			if (in_array($captures[1], $this->cocoa_classes)) {
-				$type = "$type_clean$this->class_pointer_suffix";
-				//$modifiers = "var ";
-			}
-		}
-		
-		// clean the type
-		$type = trim($type, "* ");
-		
-		//print("$type\n");
-		return $type;
-	}
-	
-	// Performs additional formatting on Objective-c parameter types		
-	function FormatObjcParams ($string) {
-		$params = explode(":", $string);
-		$string = "";
-		
-		if (count($params) > 0) {
-			foreach ($params as $value) {
-				if (ereg("\((.*)\)", $value, $captures)) {
-					$new_value = $this->ReplaceObjcType($captures[1]);
-					
-					if ($new_value != $captures[1]) $value = ereg_replace("\((.*)\)", "($new_value)", $value);
-					
-					$string .= ":$value";
-				}
-			}
-		}
-		
-		$string = ltrim($string, ":");
-		//print("$string\n");
-		return $string;
-	}
-	
-	// Converts an Objective-c parameter string to Pascal		
-	function ConvertObjcParamsToPascal ($string, $protected_keywords, &$variable_arguments) {
-		$params = explode(":", $string);
-		$list = array();
-		$list["pairs"] = array();
-		$param_list = array();
-		$variable_arguments = false;
-		
-		if (count($params) > 0) {
-			//print_r($params);
-			foreach ($params as $value) {
-				$value = trim($value);
-				$valid = false;
-				$modifiers = "";
-				
-				// function pointer (callback)
-				if (eregi("\(([a-zA-Z0-9_]+)[[:space:]]\((.*)\)\((.*)\)\)([a-zA-Z0-9_]+)", $value, $captures)) {
-					$name = $captures[4];
-					
-					$type = $this->current_header["name_clean"].ucwords($name);
-					
-					// attempt to build a function pointer from the parameter and append the class type
-					if ($this->current_header) {
-						$function_pointer = $this->ConvertFunctionPointerToPascal($captures[1], $captures[3]);
-						
-						if (!@in_array($function_pointer, $this->current_header["types"]["callbacks"])) {
-							$count = 0;
-							while (@array_key_exists($type, $this->current_header["types"]["callbacks"])) {
-								$count ++;
-								$type = "$type$count";
-							}
-							
-							// append the new type to the the current class
-							$this->current_header["types"]["callbacks"][$type] = $function_pointer;  
-						} else {
-							// Use the name of the existing callback of matching type
-							$type = array_search($function_pointer, $this->current_header["types"]["callbacks"]);
-						}
-					}
-					
-					$valid = true;
-				} elseif (eregi("\(([a-zA-Z_]+).*\)([a-zA-Z_]+).*\.\.\.", $value, $captures)) { // variable arguments
-					$name = $captures[2];
-					$type = $captures[1];
-					$variable_arguments = true;
-					$valid = true;
-				} elseif (eregi("\((.*)\)[[:space:]]*([a-zA-Z_]+)", $value, $captures)) { // standard parameter
-					
-					// pointers params to non-object types (NSRange *)
-					if (ereg("[a-zA-Z0-9_]+Ptr$", $captures[2])) { 
-						$captures[1] = trim($captures[1], "* ");
-						$captures[1] = $this->ReplaceObjcType($captures[1]);
-
-						$type = $captures[1].$this->class_pointer_suffix;//$this->ReplacePointerType($captures[1]);
-						$name = $captures[2];
-					} else {
-						$type = $this->FormatObjcType($captures[1], $modifiers);
-						$name = $captures[2];
-					}
-					
-					
-					$valid = true;
-				}
-				
-				if ($valid) {
-					
-					// protect reserved keywords
-					if ($this->IsKeywordReserved($name)) $name .= "_";
-					
-					if (!in_array($type, $this->reserved_types)) {
-						if ($this->IsKeywordReserved($type)) $type .= "_";
-					}
-
-					if (@in_array($name, $protected_keywords)) $name .= "_";
-					if (@in_array($type, $protected_keywords)) $type .= "_";
-					
-					// replace objc types
-					$type = $this->ReplaceObjcType($type);
-					$type = $this->ReplaceTollFreeBridgeType($type);
-					
-					// make sure we label duplicate params, which are allowed in Objective-C
-					while (in_array($name, $param_list)) {
-						$count ++;
-						$name = "$name$count";
-					}
-					
-					// id is always a wrapper
-					if (($this->objects_are_wrappers) && ($type == $this->objc_id)) {
-						$name_list = "$type(GetHandle($name))";
-					} else {
-						$name_list = $name;
-					}
-					
-					// add modifiers to the name if there are any
-					$name_with_modifiers = $modifiers.$name;
-
-					// create pair array
-					$pair["name"] = $name;
-					$pair["type"] = $type;
-					
-					// append list
-					$list["pairs"][] = $pair;
-					$list["string_with_modifiers"] .= "$name_with_modifiers: $type; ";
-					$list["string"] .= "$name: $type; ";
-					$list["list"] .= "$name_list, ";
-					$param_list[] = $name;
-				}
-			}
-		}
-		
-		// clean up the strings
-		$list["string"] = trim($list["string"], "; ");
-		$list["string_with_modifiers"] = trim($list["string_with_modifiers"], "; ");
-		$list["list"] = trim($list["list"], ", ");
-		
-		return $list;
-	}
-
-	// Converts an Objective-c method name to Pascal
-	function ConvertObjcMethodName ($method) {
-		$params = explode(":", $method);
-		$name = "";
-		
-		if (count($params) > 1) {
-			foreach ($params as $value) {
-				if (eregi("([a-zA-Z0-9]+)$", $value, $captures)) $name .= $captures[1]."_";
-			}
-		} else {
-			if (eregi("([a-zA-Z0-9]+)(;)*$", $params[0], $captures)) $name .= $captures[1]."_";
-		}
-		
-		// clean it up
-		if (!$this->trailing_underscore) $name = trim($name, "_");
-		
-		$name = $this->ReplaceObjcType($name);
-		
-		return $name;
-	}	
-	
-	// Converts an Objective-C method to Pascal format 
-	function ConvertObjcMethodToPascal ($class, $source, $parts, $protected_keywords, $has_params) {
-		
-		// replace "hinted" params comment with hinted type
-		if ($this->replace_hinted_params) {
-			
-			// param string
-			if (eregi("(/\*[[:space:]]*(.*)[[:space:]]*\*/)", $parts[4], $captures)) {
-				// ??? change the parameter to the hinted type
-				//$parts[4] = eregi_replace("(/\*.*\*/)", $captures[2], $parts[4]);
-				//$parts[4] = trim($parts[4], " ");
-			}
-
-			// return type
-			if (eregi("(/\*[[:space:]]*(.*)[[:space:]]*\*/)", $parts[2], $captures)) $parts[2] = $captures[2];
-
-			//print_r($parts);
-
-		} else { // remmove comments from params and return type
-			$parts[4] = eregi_replace("(/\*.*\*/)", "", $parts[4]);
-			$parts[4] = trim($parts[4], " ");
-
-			$parts[2] = eregi_replace("(/\*.*\*/)", "", $parts[2]);
-			$parts[2] = trim($parts[2], " ");
-		}
-		
-		$return_type_clean = $parts[2];
-		
-		// perform preformatting before attempting to protect keywords
-		$parts[2] = $this->FormatObjcType($parts[2], $modifiers);
-		$parts[4] = $this->FormatObjcParams($parts[4]);
-		
-		// protect keywords in the parameter and return type
-		if (count($protected_keywords) > 0) {
-			foreach ($protected_keywords as $keyword) {
-				$parts[4] = istr_replace_word($keyword, $keyword."_", $parts[4]);
-				$parts[2] = istr_replace_word($keyword, $keyword."_", $parts[2]);
-			}
-		}
-		
-		if ($has_params) {
-			$name = $this->ConvertObjcMethodName($source);
-			
-			// merge default protected keywords for the class/category
-			if ($this->default_protected["*"]) $protected_keywords = array_merge($this->default_protected["*"], $protected_keywords);
-			if ($this->default_protected[$class]) $protected_keywords = array_merge($this->default_protected[$class], $protected_keywords);
-			
-			$param_array = $this->ConvertObjcParamsToPascal($parts[4], $protected_keywords, $variable_arguments);
-			$params = "(".$param_array["string"].")";
-			$params_with_modifiers = "(".$param_array["string_with_modifiers"].")";
-		} else {
-			$params = "";
-			$params_with_modifiers = "";
-			$name = $parts[3];
-			$param_array = null;
-		}
-		
-		//print("$params_with_modifiers\n");
-		
-		// protect method name from keywords
-		if ($this->IsKeywordReserved($name)) $name .= "_";
-		
-		// clean return type
-		$return_type = trim($parts[2], "* ");
-		$return_type = $this->ReplaceObjcType($return_type);
-		$return_type = $this->ReplaceTollFreeBridgeType($return_type);
-		
-		$virtual = "";
-		$class_prefix = "";
-		
-		// determine the type based on return value
-		if (ereg($this->regex_procedure_type, $return_type_clean)) {
-			$kind = "procedure";
-		} else {
-			$kind = "function";
-			
-			// make sure Objective-c objects that are returned from fuctions are not NSObject (and thus auto-wrapped)
-			if ($return_type == $this->objc_id) $return_type = $this->objc_id_real;
-			
-			// method name starts with "init or alloc"
-			if ((ereg("^(init|alloc)+[^ialization]", $name)) && ($parts[1] == "-")) {
-				$struct["alloc"] = true;
-				$kind = "constructor";
-				$virtual = " virtual;";
-			}
-
-			// Class methods with the words: With, By or From in the name
-			if ((ereg("^([a-zA-Z]+)(With|By|From)+", $name, $captures)) && ($parts[1] == "+")) $kind = "constructor";
-			
-			// Class methods which return "id" are constructors
-			if (($parts[1] == "+") && ($return_type == $this->objc_id_real)) $kind = "constructor";
-			
-			// method result is the class name
-			if ($return_type == $class) $kind = "constructor";
-		}
-		
-		// determine if this is a class method
-		if (($kind != "constructor") && ($parts[1] == "+")) $class_prefix = "class ";
-		
-		// Determine if the method needs a particular modifier
-		// ??? THIS IS NOT COMPILING???
-		//if (ereg($this->objc_object_array, $params)) $modifier = " cdecl;";
-		
-		// Replace SEL with the string equivalent
-		if ($this->register_selectors) {
-			$params_with_modifiers = str_replace_word("SEL", $this->sel_string, $params_with_modifiers);
-		}
-		
-		// make method templates
-		if ($kind != "function") {
-			$method = "$class_prefix$kind $name$params_with_modifiers;$modifier$virtual";
-			$method_template = "[KIND] [PREFIX]$name"."[PARAMS];$modifier";
-		} else {
-			$method = $class_prefix."function $name$params_with_modifiers: $return_type;$modifier$virtual";
-			$method_template = "[KIND] [PREFIX]$name"."[PARAMS]: [RETURN];$modifier";
-			$method_template_function = "function [PREFIX]$name"."[PARAMS]: [RETURN];$modifier";
-		}
-		
-		$method_template_procedure = "procedure [PREFIX]$name"."[PARAMS];$modifier";
-		$method_template_function = "function [PREFIX]$name"."[PARAMS]: [RETURN];$modifier";
-		
-		// ??? DEBUGGING
-		//print("$method\n");
-				
-		// build structure
-		$struct["def"] = $method;
-		$struct["template"] = $method_template;
-		$struct["template_function"] = $method_template_function;
-		$struct["template_procedure"] = $method_template_procedure;
-		$struct["objc_method"] = $this->CopyObjcMethodName($source);
-		$struct["class_prefix"] = $class_prefix;
-		//$struct["def_objc"] = eregi("(.*);", $source, $captures[1]);
-		if ($return_type == "void") $return_type = "";
-		$struct["return"] = $return_type;
-		if (in_array($return_type, $this->cocoa_classes)) $struct["returns_wrapper"] = true;
-		$struct["param_string_clean"] = trim($params, "()");
-		$struct["param_string_clean_with_modifiers"] = trim($params_with_modifiers, "()");
-		$struct["param_string"] = $params;
-		$struct["param_string_with_modifiers"] = $params_with_modifiers;
-		$struct["param_array"] = $param_array["pairs"];
-		$struct["param_list"] = $param_array["list"];
-		$struct["class"] = $class;
-		$struct["name"] = $name;
-		$struct["kind"] = $kind;
-		
-		if ($struct["param_array"] != null) $struct["has_params"] = true;
-		
-		// determine if the method can be overridden
-		// (!eregi("^(set|get|is)+", $name))
-		if ($kind != "constructor") $struct["can_override"] = true;
-		
-		/*
-			TEMPORARY! we don't know how to handle super methods that have have floating point values
-		*/	
-		if (in_array($struct["return"], $this->float_types)) {
-			$struct["can_override"] = false;
-			print("	# WARNING: method $name can't override because the return type is float\n");
-			$this->warning_count ++;
-		}
-		
-		// FPC bug work around
-		if (strlen($name) > $this->maximum_method_length) {
-			$struct["can_override"] = false;
-			print("	# WARNING: method $name can't override because the name is too long\n");
-			$this->warning_count ++;
-		}
-			
-		return $struct;
-	}
-	
-	// Print string to output file
-	function PrintOutput ($indent, $string) {
-		for ($i=0; $i < $indent; $i++) { 
-			$indent_string .= "  ";
-		}
-		
-		if (($this->output) && (!$this->show)) fwrite($this->output, "$indent_string$string\n");
-		
-		if ($this->show) print("$indent_string$string\n");
-	}
-	
-	// Returns the message sending template for a method structure
-	function GetMsgSendTemplate ($method, $super) {
-		if ($method["kind"] == "function") {
-			if ($method["has_params"]) {
-				$template = $this->template_function_objc_send;
-			} else {
-				$template = $this->template_function_objc_send_no_params;
-			}
-		} else {
-			if ($method["has_params"]) {
-				$template = $this->template_procedure_objc_send;
-			} else {
-				$template = $this->template_procedure_objc_send_no_params;
-			}
-		}
-		
-		// method returns a NS*** class wrapper. Now, super methods can't return wrappers
-		if (!$super) {
-			if (($method["kind"] == "function") && (in_array($method["return"], $this->cocoa_classes))) {
-				if ($method["has_params"]) {
-					$template = $this->template_function_make_wrapper;
-				} else {
-					$template = $this->template_function_make_wrapper_no_params;
-				}
-			}
-		}
-		
-		// method returns a struct
-		if (($method["kind"] == "function") && (in_array($method["return"], $this->struct_types))) {
-			if ($method["has_params"]) {
-				$template = $this->template_function_objc_send_struct;
-			} else {
-				$template = $this->template_function_objc_send_no_params_struct;
-			}
-		}
-		
-		// method returns an architecture dependent struct
-		if (($method["kind"] == "function") && (in_array($method["return"], $this->struct_register_types))) {
-			if ($method["has_params"]) {
-				$template = $this->template_function_objc_send_struct_cpu;
-			} else {
-				$template = $this->template_function_objc_send_no_params_struct_cpu;
-			}
-		}
-		
-		// method is a constructor
-		if ($method["kind"] == "constructor") {
-			$template = $this->template_constructor_no_alloc;
-			if ($method["alloc"]) $template = $this->template_constructor;
-		}
-		
-		return $template;
-	}
-	
-	// Returns a class hierarchy array 
-	function GetClassHierarchy ($class, &$hierarchy) {
-		if (!$hierarchy) $hierarchy = array();
-		$hierarchy[] = $class["name"];
-		
-		if ($class["super_class"]) {
-			$hierarchy[] = $this->GetClassHierarchy($class["super_class"], $hierarchy);
-		} else {
-			$hierarchy[] = "NSObject";
-		}
-		
-		return $class["name"];
-	}
-	
-	// returns if a keyword is protected in a class hierarchy
-	function IsKeywordProtected ($keyword, $in_class) {
-		$keywords = $this->GetClassHierarchy($in_class, $hierarchy);
-		
-		foreach ($hierarchy as $key) {
-			if (@in_array($keyword, $keywords)) { //$this->dump["master"][$key]["protected_keywords"]
-				return true;
-			}
-		}
-	}
-	
-	// Returns all protected keywords in a class hierarchy
-	function GetProtectedKeywords ($in_class) {
-		$this->GetClassHierarchy($in_class, $hierarchy);
-		$keywords = array();
-		
-		foreach ($hierarchy as $class) {
-			if ($this->dump["master"][$class]["protected_keywords"]) {
-				foreach ($this->dump["master"][$class]["protected_keywords"] as $keyword) $keywords[] = $keyword;
-			}
-		}
-		
-		return $keywords;
-	}
-	
-	
-	// Returns header a category should be moved to
-	function FindCategoryHeader ($category) {
-		
-		foreach ($this->dump as $name => $header) {
-			if ((@array_key_exists($category, $header["classes"])) && ($category != "NSObject")) {
-				return $name;
-			}
-		}
-	}
-	
-	// Adds a method structure to a class and performs checks for overloaded methods
-	function AddMethodToClass (&$method, &$class) {
-		
-		// ignore methods
-		if (in_array($method["name"], $this->ignore_methods)) return false;
-		
-		if (@!in_array($method["name"], $class["declared_methods"])) {
-			
-			$class["all"][$method["name"]] = $method;
-			$class["protected_keywords"][] = $method["name"];
-			$class["declared_methods"][] = $method["name"];
-			$this->dump["all_methods"][$class["name"]][] = $method["objc_method"];
-			
-			if ($this->show_added_messages) print("	@ Added ".$method["name"]." to ".$class["name"]."\n");
-
-			$this->method_count ++;
-			return true;
-		} else {
-			print("	! ".$method["def"]." already exists in ".$class["name"]." defined as ".$class["all"][$method["name"]]["def"]."\n");
-		}
-	}
-	
-	// Adds a typedef to the header and handles organization to prevent order conflicts
-	function AddTypeDef (&$header, $typedef) {
-		$header["types"]["typedef"][] = $typedef;
-	}
-		
-	// Returns a paramater list string with options to modify
-	function MakeParamList ($param_array, $use_handle, $cast_handle, $direct, $register_selector) {
-		$params = "";
-		foreach ($param_array as $pair) {
-			
-			// register selector parameters
-			if (($register_selector) && ($pair["type"] == "SEL")) {
-				$params .= "sel_registerName(".$pair["name"]."), ";
-				continue;
-			}
-			
-			// use the object handle for NSObject descendants
-			if ($use_handle) {
-				if (in_array($pair["type"], $this->cocoa_classes)) {
-
-					// cast the param to the original class type
-					if ($cast_handle) {
-						if ($direct == ACCESS_HANDLE_DIRECT) {
-							$params .= $pair["type"]."(".$pair["name"].".Handle), ";
-						} else {
-							$params .= $pair["type"]."(GetHandle(".$pair["name"].")), ";
-						}
-					} else {
-						if ($direct == ACCESS_HANDLE_DIRECT) {
-							$params .= $pair["name"].".Handle, ";
-						} else {
-							$params .= "GetHandle(".$pair["name"]."), ";
-						}
-					}
-
-				} else {
-					if (($this->objects_are_wrappers) && ($pair["type"] == $this->objc_id)) {	// id is always a wrapper
-						if ($direct == ACCESS_HANDLE_DIRECT) {
-							$params .= $pair["type"]."(".$pair["name"].".Handle), ";
-						} else {
-							$params .= $pair["type"]."(GetHandle(".$pair["name"].")), ";
-						}
-					} else {
-						$params .= $pair["name"].", ";
-					}
-				}
-			} else { // append without modification
-				$params .= $pair["name"].", ";
-			}
-		}
-		
-		return trim($params, ", ");
-	}
-	
-	// Returns a list of paramameter variables with NS*** class types cast to "id" or the original class
-	function MakeObjcTypeParamList ($param_array, $objc_type) {
-		$params = "";
-		foreach ($param_array as $pair) {
-			if (in_array($pair["type"], $this->cocoa_classes)) {
-				if ($objc_type) {
-					$params .= "$this->objc_id(".$pair["name"]."), ";
-				} else {
-					$params .= $pair["type"]."(".$pair["name"]."), ";
-				}
-			} else {
-				$params .= $pair["name"].", ";
-			}
-		}
-		return trim($params, ", ");
-	}
-	
-	/**
-	 * PRINTING METHODS
-	 */
-			
-	// Prints implemented methods
-	function PrintImplementedMethods ($class) {
-		
-		// print implemented methods
-		$this->PrintOutput(0, "");
-		$this->PrintOutput(0, "{ Implemented methods }");
-		foreach ($class["all"] as $method) {
-			if ($method["can_override"]) {
-			
-				if ($method["kind"] == "function") {
-					$template = $this->template_implemented_function;
-				} else {
-					$template = $this->template_implemented_procedure;
-				}
-				
-				$template = str_replace("[CLASS]", $class["name"], $template);
-				$template = str_replace("[NAME]", $method["name"], $template);
-				
-				$method["return"] = $this->ReplaceNSTypesWithRef($method["return"]);
-				$template = str_replace("[RETURN]", $method["return"], $template);
-				$template = str_replace("[PARAMS_HEADER]", $method["param_string_with_modifiers"], $template);
-				
-				// build parameter list
-				if ($method["has_params"]) {
-					
-					// auto-generate wrappers
-					$params = "(";
-					$params .= $this->MakeParamList($method["param_array"], USE_HANDLE, CAST_HANDLE, ACCESS_HANDLE_FUNCTION, DONT_REGISTER_SEL);
-					$params .= ")";
-					$template = str_replace("[PARAMS_BODY_WRAPPER]", $params, $template);
-					
-					// standard params
-					$params = "(";
-					$params .= $this->MakeObjcTypeParamList($method["param_array"], true);
-					$params .= ")";
-					$template = str_replace("[PARAMS_BODY]", $params, $template);
-					
-					
-				} else {
-					$template = str_replace("[PARAMS_BODY]", "", $template);
-					$template = str_replace("[PARAMS_BODY_WRAPPER]", "", $template);
-				}
-
-				$this->PrintOutput(0, "");
-				$this->PrintOutput(0, $template);
-			}
-		}
-		
-	}
-				
-	// Prints Objective-C wrapper procedures
-	function PrintObjcWrapperProcedures ($class) {
-		
-		// print implemented methods
-		$this->PrintOutput(0, "");
-		$this->PrintOutput(0, "{ Objective-c wrapper procedures }");
-		foreach ($class["all"] as $method) {
-			if ($method["can_override"]) {
-			
-				if ($method["kind"] == "function") {
-					$template = $this->template_function_objc_wrapper;
-				} else {
-					$template = $this->template_procedure_objc_wrapper;
-				}
-				
-				$template = str_replace("[CLASS]", $class["name"], $template);
-				$template = str_replace("[NAME]", $method["name"], $template);
-				$template = str_replace("[SELNAME]", str_replace(":", "_", $method["objc_method"]), $template);
-				
-				$method["return"] = $this->ReplaceNSTypesWithRef($method["return"]);
-				$template = str_replace("[RETURN]", $method["return"], $template);
-				
-				if ($method["has_params"]) {
-					$method["param_string_clean"] = $this->ReplaceNSTypes($method["param_string_clean"]);
-					
-					// Make sure we always the id type in objc wrappers
-					$params_header = $this->ReplaceNSTypesWithRef($method["param_string_clean_with_modifiers"]);
-					$template = str_replace("[PARAMS_HEADER]", "; $params_header", $template);
-					
-					// auto-generate wrappers
-					$wrappers_variables = "";
-					$wrappers_create = "";
-					$wrappers_release = "";
-					$variable_list = "";
-					
-					foreach ($method["param_array"] as $pair) {
-						if (in_array($pair["type"], $this->cocoa_classes)) {
-							
-							$wrappers_variables .= "object_".$pair["name"].": ".$pair["type"]."\n;";
-							$wrappers_create .= "object_".$pair["name"]." := ".$pair["type"].".CreateWithHandle(".$pair["name"].");\n";
-							$wrappers_release .= "object_".$pair["name"].".release;\n";
-							$variable_list .= "object_".$pair["name"].", ";
-						} else {
-							$variable_list .= $pair["name"].", ";
-						}
-					}
-					$variable_list = trim($variable_list, ", ");
-					
-					$template = str_replace("[VARIABLES]", $wrappers_variables, $template);
-					$template = str_replace("[WRAPPERS_CREATE]", $wrappers_create, $template);
-					$template = str_replace("[WRAPPERS_RELEASE]", $wrappers_release, $template);
-					
-					$template = str_replace("[PARAMS_LIST_WRAPPER]", "($variable_list)", $template);
-					
-					$params = $this->MakeObjcTypeParamList($method["param_array"], false);
-					$template = str_replace("[PARAMS_LIST]", "($params)", $template);
-					
-				} else {
-					$template = str_replace("[PARAMS_HEADER]", "", $template);
-					$template = str_replace("[PARAMS_LIST]", "", $template);
-					$template = str_replace("[PARAMS_LIST_WRAPPER]", "", $template);
-					$template = str_replace("[VARIABLES]", "", $template);
-					$template = str_replace("[WRAPPERS_CREATE]", "", $template);
-					$template = str_replace("[WRAPPERS_RELEASE]", "", $template);
-				}
-				
-				$this->PrintOutput(0, "");
-				$this->PrintOutput(0, $template);
-			}
-		}
-	}
-	
-	// Prints send message objects with a custom implementation
-	function PrintCustomSendMessageMethods ($class, $method) {
-		
-		// NSArray
-		if ($class["name"] == "NSArray") {
-			if ($method["name"] == "arrayWithObjects") $template = $this->template_constructor_constarray_no_alloc; 
-			if ($method["name"] == "initWithObjects") $template = $this->template_constructor_constarray; 
-			
-			$template = str_replace("[CFTYPE]", "CFArrayRef", $template);
-			$template = str_replace("[ALLOC_PARAM_LIST]", $this->template_array_param_list, $template);
-			
-			if ($method["name"] == "arrayWithObjects") $template = str_replace("[OBJC_METHOD]", "arrayWithArray:", $template);
-			if ($method["name"] == "initWithObjects") $template = str_replace("[OBJC_METHOD]", "initWithArray:", $template);
-		}
-		
-		// NSDictionary
-		if ($class["name"] == "NSDictionary") {
-			if ($method["name"] == "dictionaryWithObjectsAndKeys") $template = $this->template_constructor_constarray_no_alloc; 
-			if ($method["name"] == "initWithObjectsAndKeys") $template = $this->template_constructor_constarray; 
-			
-			$template = str_replace("[CFTYPE]", "CFDictionaryRef", $template);
-			$template = str_replace("[ALLOC_PARAM_LIST]", $this->template_dictionary_param_list, $template);
-			
-			if ($method["name"] == "dictionaryWithObjectsAndKeys") $template = str_replace("[OBJC_METHOD]", "dictionaryWithDictionary:", $template);
-			if ($method["name"] == "initWithObjectsAndKeys") $template = str_replace("[OBJC_METHOD]", "initWithDictionary:", $template);
-		}
-		
-		// NSSet
-		if ($class["name"] == "NSSet") {
-			if ($method["name"] == "setWithObjects") $template = $this->template_constructor_constarray_no_alloc; 
-			if ($method["name"] == "initWithObjects") $template = $this->template_constructor_constarray; 
-			
-			$template = str_replace("[CFTYPE]", "CFSetRef", $template);
-			$template = str_replace("[ALLOC_PARAM_LIST]", $this->template_set_param_list, $template);
-			
-			if ($method["name"] == "setWithObjects") $template = str_replace("[OBJC_METHOD]", "setWithSet:", $template);
-			if ($method["name"] == "initWithObjects") $template = str_replace("[OBJC_METHOD]", "initWithSet:", $template);
-		}
-		
-		$template = str_replace("[PARAMS_HEADER]", $method["param_string_with_modifiers"], $template);			
-		$template = str_replace("[CLASS]", $class["name"].".", $template);
-		$template = str_replace("[NAME]", $method["name"], $template);
-		$template = str_replace("[SELNAME]", str_replace(":", "_", $method["objc_method"]), $template);
-		
-		$this->PrintOutput(0, "");
-		$this->PrintOutput(0, $template);
-	}
-				
-	// Prints send message objects
-	function PrintSendMessageMethods ($class) {
-
-		$this->PrintOutput(0, "");
-		$this->PrintOutput(0, "{ Objective-c send message methods }");
-		foreach ($class["all"] as $method) {
-			
-			// handle custom methods
-			if (in_array($class["name"].".".$method["name"], $this->custom_send_methods)) {
-				$this->PrintCustomSendMessageMethods($class, $method);
-				continue;
-			}
-			
-			$template = $this->GetMsgSendTemplate($method, false);
-			
-			$template = $method["class_prefix"].$template;
-			
-			$template = str_replace("[CLASS]", $class["name"].".", $template);
-			$template = str_replace("[NAME]", $method["name"], $template);
-			$template = str_replace("[SELNAME]", str_replace(":", "_", $method["objc_method"]), $template);
-			$template = str_replace("[RETURN]", $method["return"], $template);
-			
-			// Replace SEL with the string equivalent so it can be registered inside the wrapper
-			if ($this->register_selectors) {
-				$params_header = str_replace_word("SEL", $this->sel_string, $method["param_string_with_modifiers"]);
-				$register = REGISTER_SEL;
-			} else {
-				$params_header = $method["param_string_with_modifiers"];
-				$register = DONT_REGISTER_SEL;
-			}
-			
-			$template = str_replace("[PARAMS_HEADER]", $params_header, $template);			
-			
-			if ($method["has_params"]) {
-				$template = str_replace("[PARAMS_PROC]", "; ".$method["param_string_clean_with_modifiers"], $template);
-				
-				$params_wrapper = $this->MakeParamList($method["param_array"], USE_HANDLE, CAST_HANDLE, ACCESS_HANDLE_FUNCTION, $register);			
-				$params_list = $this->MakeParamList($method["param_array"], DONT_USE_HANDLE, DONT_CAST_HANDLE, ACCESS_HANDLE_FUNCTION, $register);	
-				
-				$template = str_replace("[PARAMS_LIST_WRAPPER]", ", ".$params_wrapper, $template);
-				$template = str_replace("[PARAMS_LIST]", ", ".$params_list, $template);
-			} else {
-				$template = str_replace("[PARAMS_PROC]", "", $template);
-				$template = str_replace("[PARAMS_LIST]", "", $template);
-				$template = str_replace("[PARAMS_LIST_WRAPPER]", "", $template);
-			}
-			
-			$template = str_replace("[TARGET_TYPE]", $this->objc_id_real, $template);
-			$template = str_replace("[OBJC_METHOD]", $method["objc_method"], $template);
-			$template = str_replace("[GET_SUPER_CLASS]", "", $template);
-			
-			// decide reference to objc object by method type
-			if ($method["class_prefix"] == "") {
-				$template = str_replace("[OBJC_OBJECT]", "Handle", $template);
-			} else {
-				$template = str_replace("[OBJC_OBJECT]", "getClass", $template);
-			}
-			
-			$template = str_replace("[MSG_SEND_STRET]", "objc_msgSend_stret", $template);
-			$template = str_replace("[MSG_SEND_REGISTER]", "objc_msgSend", $template);
-			
-			if (in_array($method["return"], $this->struct_types)) {		// structure
-				$template = str_replace("[MSG_SEND]", "objc_msgSend_stret", $template);
-			} elseif (in_array($method["return"], $this->float_types)) {		// floating point
-				$template = str_replace("[MSG_SEND]", "objc_msgSend_fpret", $template);
-			} else { // simple type
-				$template = str_replace("[MSG_SEND]", "objc_msgSend", $template);
-			}
-			
-			$this->PrintOutput(0, "");
-			$this->PrintOutput(0, $template);
-		}
-	}
-	
-	// Prints override methods
-	function PrintOverrideMethods ($class) {
-
-		$this->PrintOutput(0, "");
-		$this->PrintOutput(0, "{ Override methods }");
-		foreach ($class["all"] as $method) {
-			if ($method["can_override"]) {
-			
-				$template = $this->template_method_override;
-				
-				$template = str_replace("[CLASS]", $class["name"], $template);
-				$template = str_replace("[NAME]", $method["name"], $template);
-				$template = str_replace("[SELNAME]", str_replace(":", "_", $method["objc_method"]), $template);
-				$template = str_replace("[OBJC_METHOD]", $method["objc_method"], $template);
-				$template = str_replace("[TYPE_ENCODING]", $this->type_encodings[$class["name"]][$method["objc_method"]], $template);
-				
-				$this->PrintOutput(0, "");
-				$this->PrintOutput(0, $template);
-			}
-		}
-	}
-	
-	// Prints implemented methods that contain sending code
-	function PrintImplementedSuperMethods ($class) {
-		
-		$this->PrintOutput(0, "");
-		$this->PrintOutput(0, "{ Implemented methods }");
-		foreach ($class["all"] as $method) {
-			if ($method["can_override"]) {
-			
-				$template = $this->GetMsgSendTemplate($method, true);
-				
-				$template = str_replace("[CLASS]", $class["name"].".", $template);
-				$template = str_replace("[NAME]", "implemented_".$method["name"], $template);
-				$template = str_replace("[SELNAME]", str_replace(":", "_", $method["objc_method"]), $template);
-				$method["return"] = $this->ReplaceNSTypesWithRef($method["return"]);
-				$template = str_replace("[RETURN]", $method["return"], $template);
-
-				// Replace SEL with the string equivalent so it can be registered inside the wrapper
-				if ($this->register_selectors) {
-					$params_header = str_replace_word("SEL", $this->sel_string, $method["param_string_with_modifiers"]);
-					$register = REGISTER_SEL;
-				} else {
-					$params_header = $method["param_string_with_modifiers"];
-					$register = DONT_REGISTER_SEL;
-				}
-				$template = str_replace("[PARAMS_HEADER]", $params_header, $template);			
-
-				if ($method["has_params"]) {
-					$template = str_replace("[PARAMS_PROC]", "; ".$method["param_string_clean_with_modifiers"], $template);
-
-					$params_wrapper = $this->MakeParamList($method["param_array"], USE_HANDLE, CAST_HANDLE, ACCESS_HANDLE_FUNCTION, $register);			
-					$params_list = $this->MakeParamList($method["param_array"], DONT_USE_HANDLE, DONT_CAST_HANDLE, ACCESS_HANDLE_FUNCTION, $register);	
-
-					$template = str_replace("[PARAMS_LIST_WRAPPER]", ", ".$params_wrapper, $template);
-					$template = str_replace("[PARAMS_LIST]", ", ".$params_list, $template);
-				} else {
-					$template = str_replace("[PARAMS_PROC]", "", $template);
-					$template = str_replace("[PARAMS_LIST]", "", $template);
-				}
-				
-				$template = str_replace("[TARGET_TYPE]", "Pobjc_super", $template);
-				$template = str_replace("[OBJC_METHOD]", $method["objc_method"], $template);
-				$template = str_replace("[OBJC_OBJECT]", "@super", $template);
-				$template = str_replace("[GET_SUPER_CLASS]", "super := getSuperClass;", $template);
-				
-				$template = str_replace("[MSG_SEND_STRET]", "objc_msgSendSuper_stret", $template);
-				$template = str_replace("[MSG_SEND_REGISTER]", "objc_msgSendSuper", $template);
-				
-				if (in_array($method["return"], $this->struct_types)) {
-					$template = str_replace("[MSG_SEND]", "objc_msgSendSuper_stret", $template);
-				} else {
-					$template = str_replace("[MSG_SEND]", "objc_msgSendSuper", $template);
-				}
-				
-				$this->PrintOutput(0, "");
-				$this->PrintOutput(0, $template);
-			}
-		}
-	}
-		
-	// Prints super methods
-	function PrintSuperMethods ($class) {
-		
-		$this->PrintOutput(0, "");
-		$this->PrintOutput(0, "{ Super methods }");
-		foreach ($class["all"] as $method) {
-			if ($method["can_override"]) {
-			
-				$template = $this->GetMsgSendTemplate($method, true);
-				
-				$template = str_replace("[CLASS]", $class["name"].".", $template);
-				$template = str_replace("[NAME]", "super_".$method["name"], $template);
-				$template = str_replace("[SELNAME]", str_replace(":", "_", $method["objc_method"]), $template);
-				
-				$method["return"] = $this->ReplaceNSTypesWithRef($method["return"]);
-				$template = str_replace("[RETURN]", $method["return"], $template);
-				
-				//$method["param_string"] = $this->ReplaceNSTypesWithReal($method["param_string"]);
-				//$method["param_string_clean"] = $this->ReplaceNSTypesWithReal($method["param_string_clean"]);
-				
-				$template = str_replace("[PARAMS_HEADER]", $method["param_string_with_modifiers"], $template);
-				$template = str_replace("[PARAMS_PROC]", "; ".$method["param_string_clean"], $template);
-				$template = str_replace("[PARAMS_LIST_WRAPPER]", ", ".$method["param_list"], $template);
-				$template = str_replace("[PARAMS_LIST]", ", ".$method["param_list"], $template);
-				$template = str_replace("[TARGET_TYPE]", "Pobjc_super", $template);
-				$template = str_replace("[OBJC_METHOD]", $method["objc_method"], $template);
-				$template = str_replace("[OBJC_OBJECT]", "@super", $template);
-				$template = str_replace("[GET_SUPER_CLASS]", "", $template);
-				
-				if (in_array($method["return"], $this->struct_types)) {
-					$template = str_replace("[MSG_SEND]", "objc_msgSendSuper_stret", $template);
-				} else {
-					$template = str_replace("[MSG_SEND]", "objc_msgSendSuper", $template);
-				}
-				
-				
-				$this->PrintOutput(0, "");
-				$this->PrintOutput(0, $template);
-			}
-		}
-	}
-	
-	function PrintProtocolDeclaration ($protocol, $method) {
-		$template = $method["template"];
-		$template = str_replace("[PREFIX]", $protocol["name"]."_", $template);
-		
-		if ($method["param_array"] == 0) {
-			$param = "sourceObject: NSObjectRef";
-		} else {
-			$param = "sourceObject: NSObjectRef; ";
-		}
-		
-		$template = str_replace("[PARAMS]", "($param".$method["param_string_clean_with_modifiers"].")", $template);
-		$template = str_replace("[KIND]", $method["kind"], $template);
-		$template = str_replace("[RETURN]", $method["return"], $template);
-
-		$this->PrintOutput(0, $template);
-	}
-	
-	// Prints all the protocols in the header
-	function PrintHeaderProtocols ($header, $implemented) {
-		
-		if (!$header["protocols"]) return;
-		
-		foreach ($header["protocols"] as $protocol) {
-			
-			if ($implemented) {
-				
-				if (!$protocol["methods"]) continue;
-				
-				foreach ($protocol["methods"] as $name => $method) {
-					if ($method["kind"] != "constructor") {
-						//$this->PrintProtocolDeclaration($protocol, $method);
-						
-						$template = $this->GetMsgSendTemplate($method, false);
-						
-						// choose the protocol version
-						if ($template == $this->template_function_make_wrapper) $template = $this->template_protocol_make_wrapper;
-						if ($template == $this->template_function_make_wrapper_no_params) $template = $this->template_protocol_make_wrapper_no_params;
-						
-						$template = str_replace("[CLASS]", $protocol["name"]."_", $template);
-						if ($method["param_array"] == 0) {
-							// add header params token to accommodate our extra parameter
-							$template = str_replace("[NAME]", $method["name"]."[PARAMS_HEADER]", $template);
-						} else {
-							$template = str_replace("[NAME]", $method["name"], $template);
-						}
-						$template = str_replace("[SELNAME]", str_replace(":", "_", $method["objc_method"]), $template);
-						$template = str_replace("[RETURN]", $method["return"], $template);
-
-						if ($method["param_array"] == 0) {
-							$source_param = "sourceObject: NSObjectRef";
-						} else {
-							$source_param = "sourceObject: NSObjectRef; ";
-						}
-
-						// Replace SEL with the string equivalent so it can be registered inside the wrapper
-						if ($this->register_selectors) {
-							$params_header = str_replace_word("SEL", $this->sel_string, $method["param_string_clean_with_modifiers"]);
-							$register = REGISTER_SEL;
-						} else {
-							$params_header = $method["param_string_clean_with_modifiers"];
-							$register = DONT_REGISTER_SEL;
-						}
-
-						$template = str_replace("[PARAMS_HEADER]", "($source_param$params_header)", $template);			
-
-						if ($method["has_params"]) {
-							$template = str_replace("[PARAMS_PROC]", "; ".$method["param_string_clean"], $template);
-
-							$params_wrapper = $this->MakeParamList($method["param_array"], USE_HANDLE, CAST_HANDLE, ACCESS_HANDLE_DIRECT, $register);			
-							$params_list = $this->MakeParamList($method["param_array"], DONT_USE_HANDLE, DONT_CAST_HANDLE, ACCESS_HANDLE_DIRECT, $register);	
-
-							$template = str_replace("[PARAMS_LIST_WRAPPER]", ", ".$params_wrapper, $template);
-							$template = str_replace("[PARAMS_LIST]", ", ".$params_list, $template);
-						} else {
-							$template = str_replace("[PARAMS_PROC]", "", $template);
-							$template = str_replace("[PARAMS_LIST]", "", $template);
-						}
-
-						$template = str_replace("[TARGET_TYPE]", $this->objc_id_real, $template);
-						$template = str_replace("[OBJC_METHOD]", $method["objc_method"], $template);
-						$template = str_replace("[GET_SUPER_CLASS]", "", $template);
-						
-						$template = str_replace("[MSG_SEND_STRET]", "objc_msgSend_stret", $template);
-						$template = str_replace("[MSG_SEND_REGISTER]", "objc_msgSend", $template);
-
-						// use the source object as the the target
-						$template = str_replace("[OBJC_OBJECT]", "sourceObject", $template);
-
-						if (in_array($method["return"], $this->struct_types)) {		// structure
-							$template = str_replace("[MSG_SEND]", "objc_msgSend_stret", $template);
-						} elseif (in_array($method["return"], $this->float_types)) {		// floating point
-							$template = str_replace("[MSG_SEND]", "objc_msgSend_fpret", $template);
-						} else { // simple type
-							$template = str_replace("[MSG_SEND]", "objc_msgSend", $template);
-						}
-
-						$this->PrintOutput(0, "");
-						$this->PrintOutput(0, $template);
-						
-						
-					}
-				}
-				
-			} else {
-				if ($protocol["methods"]) {
-					$this->PrintOutput(0, "");
-					$this->PrintOutput(0, "{ Protocol: ".$protocol["name"]." }");
-
-					foreach ($protocol["methods"] as $name => $method) {
-						if ($method["kind"] != "constructor") {
-							$this->PrintProtocolDeclaration($protocol, $method);
-						}
-					}
-				}
-			}
-		}
-	}
-	
-	function PrintSelectorVariables ($class) {
-		
-		// class has no methods, bail!
-		if (!$class["methods"]) return;
-		
-		$this->PrintOutput(0,"var");
-		
-		foreach ($class["all"] as $method) {
-			$sel_name = str_replace(":", "_", $method["objc_method"]);
-			$this->PrintOutput(1, "SEL_$sel_name: SEL;");
-		}
-		
-	}
-	
-	// Prints a classes implementation in Pascal format to a file handle
-	function PrintClassImplementation ($class) {
-		
-		// class has no methods, bail!
-		if (!$class["methods"]) return;
-		
-		$name = $class["name"];
-		
-		$this->PrintOutput(0,"");
-		$this->PrintOutput(0, "{ Selectors for $name }");
-		$this->PrintSelectorVariables($class);
-		
-		$this->PrintOutput(0,"");
-		$this->PrintOutput(0, "{ Implementation for $name }");
-		
-		// Global accessor object
-		$this->PrintOutput(0,"");
-		$this->PrintOutput(0,"var");
-		$this->PrintOutput(1, "__".$class["name"].": ".$class["name"].";");
-		
-		// getClass method
-		$this->PrintOutput(0,"");
-		$this->PrintOutput(0,"class function $name.getClass: $this->objc_id_real;");
-		$this->PrintOutput(0,"begin");
-		$this->PrintOutput(1,"Result := objc_getClass('$name');");
-		$this->PrintOutput(0,"end;");
-		
-		// withObject static accessor
-		$this->PrintOutput(0,"");
-		$this->PrintOutput(0, "class function $name.withObject (inObject: Pointer): $name;");
-		$this->PrintOutput(0,"begin");
-		$this->PrintOutput(1,"if __$name = nil then");
-		$this->PrintOutput(2,"__$name := $name.Create;");
-		$this->PrintOutput(1,"__$name.Handle := inObject;");
-		$this->PrintOutput(1,"result := __$name;");
-		$this->PrintOutput(0,"end;");
-		
-		$this->PrintImplementedSuperMethods($class);
-		// DEPRECTAED IN FAVOR OF IMPLEMENTED SUPER METHODS
-		//$this->PrintImplementedMethods($class);
-		//$this->PrintSuperMethods($class);
-		$this->PrintObjcWrapperProcedures($class);
-		$this->PrintOverrideMethods($class);
-		$this->PrintSendMessageMethods($class);
-	}
-	
-	// Prints a calls in Pascal format to a file handle
-	public function PrintClass ($class) {
-		
-		// class has no methods, bail!
-		if (!$class["methods"]) return;
-		
-		// the delegate class is the super class of NSObject
-		if ($class["name"] == "NSObject") $class["super"] = $this->master_delegate_class;
-		
-		$this->PrintOutput(0, "");
-		$this->PrintOutput(0, "{ ".$class["name"]." }");
-		$this->PrintOutput(1, $class["name"]." = class(".$class["super"].")");
-		$this->PrintOutput(1, "public");
-	   
-		// getClass override
-		$this->PrintOutput(2, "class function getClass: $this->objc_id_real; override;");
-		
-		// static wrapper accessor
-		$class_name = $class["name"];
-		$this->PrintOutput(2, "class function withObject (inObject: Pointer): $class_name;");
-		
-		// print class-level methods
-		$this->PrintOutput(0, "");
-		$this->PrintOutput(2, "{ Class Methods }");
-		foreach ($class["methods"] as $method) {
-			$this->PrintOutput(2, $method["def"]);
-		}
-	
-		// print category-level methods
-		if (count($class["categories"]) > 0) {
-			foreach ($class["categories"] as $name => $category) {
-				$this->PrintOutput(0, "");
-				$this->PrintOutput(2, "{ Category: $name }");
-				
-				if ($category["methods"]) {
-					foreach ($category["methods"] as $method) {
-						$this->PrintOutput(2, $method["def"]);
-					}
-				}	
-			}
-		}
-		
-		// print implemented methods
-		$this->PrintOutput(0, "");
-		$this->PrintOutput(1, "protected");
-		$this->PrintOutput(2, "{ Implemented Methods }");
-		foreach ($class["all"] as $method) {
-			if ($method["can_override"]) {
-			
-				$template = $method["template"];
-				$template = str_replace("[PREFIX]", "implemented_", $template);
-				$template = str_replace("[PARAMS]", $method["param_string_with_modifiers"], $template);
-				$template = str_replace("[KIND]", $method["kind"], $template);
-				
-				// implemented methods always return id instead of wrappers
-				$method["return"] = $this->ReplaceNSTypesWithRef($method["return"]);
-				
-				$template = str_replace("[RETURN]", $method["return"], $template);
-				
-				$this->PrintOutput(2, $template." virtual;");
-			}
-		}
-		
-		// print override methods
-		$this->PrintOutput(0, "");
-		$this->PrintOutput(2, "{ Override Methods }");
-		foreach ($class["all"] as $method) {
-			if ($method["can_override"]) {
-			
-				$template = $method["template_procedure"];
-				$template = str_replace("[PREFIX]", "override_", $template);
-				$template = str_replace("[PARAMS]", "", $template);
-				$template = str_replace("[RETURN]", "", $template);
-				
-				$this->PrintOutput(2, $template);
-			}
-		}
-		
-		// print super methods
-		/* DEPRECTAED IN FAVOR OF IMPLEMENTED SUPER METHODS
-		$this->PrintOutput(0, "");
-		$this->PrintOutput(2, "{ Super Methods }");
-		foreach ($class["all"] as $method) {
-			if ($method["can_override"]) {
-			
-				$template = $method["template"];
-				$template = str_replace("[PREFIX]", "super_", $template);
-				$template = str_replace("[PARAMS]", $method["param_string_with_modifiers"], $template);
-				$template = str_replace("[KIND]", $method["kind"], $template);
-				$template = str_replace("[RETURN]", $this->ReplaceNSTypesWithRef($method["return"]), $template);	
-				
-				$this->PrintOutput(2, $template);
-			}
-		}
-		*/
-		$this->PrintOutput(1, "end;");
-	}
-		
-	function PrintDelegateReference ($valid_categories) {
-		
-		ksort($this->delegate_methods);
-		
-		$this->PrintOutput(0, "unit $this->master_delegate_file;");
-		$this->PrintOutput(0, "interface");
-		$this->PrintOutput(0, "uses");
-		$this->PrintOutput(1, "ctypes, objc, MacOSAll");
-
-		$this->PrintOutput(0, "type");
-		$this->PrintOutput(1, "$this->master_delegate_class = class");
-		$this->PrintOutput(1, "public");
-		
-		// implemented methods
-		foreach ($this->delegate_methods as $category => $selectors) {
-			if (in_array($category, $this->ignore_categories)) continue;
-			
-			// make sure the category is valid
-			$valid = false;
-			foreach ($valid_categories as $pattern) {
-				if (eregi($pattern, $category)) {
-					$valid = true;
-					break;
-				}
-			}
-			if (!$valid) continue;
-			
-			$this->PrintOutput(2, "");
-			$this->PrintOutput(2, "{ $category }");
-			
-			foreach ($selectors as $selector) {
-				
-				// FPC long name bug work-around
-				if (strlen($selector["name_pascal"]) > $this->maximum_method_length) continue;
-				
-				if ($selector["kind"] == "procedure") {
-					$this->PrintOutput(2, $selector["kind"]." ".$selector["name_pascal"].$selector["param_string"].";");
-				} else {
-					$this->PrintOutput(2, $selector["kind"]." ".$selector["name_pascal"].$selector["param_string"].": ".$selector["method"]["return"].";");
-				}
-				
-			}
-		}
-		
-		$this->PrintOutput(1, "end;");
-	}
-		
-		
-	function PrintDelegateClass ($valid_categories) {
-		
-		ksort($this->delegate_methods);
-		
-		$this->PrintOutput(0, "{\$ifdef FORWARD}");
-		$this->PrintOutput(1, "$this->master_delegate_class = class;");
-		$this->PrintOutput(0, "{\$endif}");
-	
-		$this->PrintOutput(0, "{\$ifdef CLASSES}");
-		$macro = strtoupper($this->master_delegate_class);
-		$this->PrintOutput(0, "{\$ifndef $macro"."_PAS_C}");
-		$this->PrintOutput(0, "{\$define $macro"."_PAS_C}");
-		
-		$this->PrintOutput(1, "$this->master_delegate_class = class(NSObjectCore)");
-		$this->PrintOutput(1, "public");
-		
-		//$this->PrintOutput(2, "constructor Create; override;");
-		
-		// implemented methods
-		foreach ($this->delegate_methods as $category => $selectors) {
-			if (in_array($category, $this->ignore_categories)) continue;
-			
-			// make sure the category is valid
-			$valid = false;
-			foreach ($valid_categories as $pattern) {
-				if (eregi($pattern, $category)) {
-					$valid = true;
-					break;
-				}
-			}
-			if (!$valid) continue;
-			
-			$this->PrintOutput(2, "");
-			$this->PrintOutput(2, "{ $category }");
-			
-			foreach ($selectors as $selector) {
-				
-				// FPC long name bug work-around
-				if (strlen($selector["name_pascal"]) > $this->maximum_method_length) continue;
-				
-				if ($selector["kind"] == "procedure") {
-					$this->PrintOutput(2, $selector["kind"]." ".$selector["name_pascal"].$selector["param_string"]."; virtual;");
-				} else {
-					$this->PrintOutput(2, $selector["kind"]." ".$selector["name_pascal"].$selector["param_string"].": ".$selector["method"]["return"]."; virtual;");
-				}
-				
-			}
-		}
-		
-		// add methods
-		$this->PrintOutput(2, "");
-		$this->PrintOutput(2, "{ Adding methods }");
-		foreach ($this->delegate_methods as $category => $selectors) {
-			if (in_array($category, $this->ignore_categories)) continue;
-			
-			// make sure the category is valid
-			$valid = false;
-			foreach ($valid_categories as $pattern) {
-				if (eregi($pattern, $category)) {
-					$valid = true;
-					break;
-				}
-			}
-			if (!$valid) continue;
-			
-			foreach ($selectors as $selector) {
-				// FPC long name bug work-around
-				if (strlen("add_".$selector["name_pascal"]) > $this->maximum_method_length) continue;
-				
-				$this->PrintOutput(2, "procedure add_".$selector["name_pascal"].";");
-			}
-		}
-		
-		$this->PrintOutput(1, "end;");
-		$this->PrintOutput(0, "{\$endif}");
-		$this->PrintOutput(0, "{\$endif}");
-		$this->PrintOutput(0, "{\$ifdef IMPLEMENTATION}");		
-		
-		// create constructor method
-		/*
-		$this->PrintOutput(0, "");
-		$template = str_replace("[CLASS]", $this->master_delegate_class, $this->template_delegate_create);
-		$this->PrintOutput(0, $template);
-		*/
-				
-		// print implemented methods
-		foreach ($this->delegate_methods as $category => $selectors) {
-			if (in_array($category, $this->ignore_categories)) continue;
-			
-			// make sure the category is valid
-			$valid = false;
-			foreach ($valid_categories as $pattern) {
-				if (eregi($pattern, $category)) {
-					$valid = true;
-					break;
-				}
-			}
-			if (!$valid) continue;
-			
-			// place-holder methods
-			foreach ($selectors as $selector) {
-
-				// FPC long name bug work-around
-				if (strlen($selector["name_pascal"]) > $this->maximum_method_length) continue;
-
-				if ($selector["kind"] == "procedure") {
-					$this->PrintOutput(0, $selector["kind"]." ".$this->master_delegate_class.".".$selector["name_pascal"].$selector["param_string"].";");
-				} else {
-					$this->PrintOutput(0, $selector["kind"]." ".$this->master_delegate_class.".".$selector["name_pascal"].$selector["param_string"].": ".$selector["method"]["return"].";");
-				}
-
-				$this->PrintOutput(0, "begin");
-				$this->PrintOutput(0, "end;");
-				$this->PrintOutput(0, "");
-			}			
-			
-			// objc wrappers
-			foreach ($selectors as $selector) {
-				
-				// FPC long name bug work-around
-				if (strlen($selector["name_pascal"]) > $this->maximum_method_length) continue;
-
-				if ($selector["kind"] == "function") {
-					$template = $this->template_function_delegate_objc;
-				} else {
-					$template = $this->template_procedure_delegate_objc;
-				}
-				
-				$template = str_replace("[CLASS]", $this->master_delegate_class, $template);
-				$template = str_replace("[NAME]", $selector["name_pascal"], $template);
-				
-				$selector["method"]["return"] = $this->ReplaceNSTypes($selector["method"]["return"]);
-				$template = str_replace("[RETURN]", $selector["method"]["return"], $template);
-				
-				if ($selector["method"]["has_params"]) {
-					$selector["method"]["param_string_clean"] = $this->ReplaceNSTypesWithRef($selector["method"]["param_string_clean"]);
-					$template = str_replace("[PARAMS_HEADER]", " (_self: $this->objc_id_real; _cmd: SEL; ".$selector["method"]["param_string_clean"].")", $template);
-					
-					// auto-generate wrappers
-					$wrappers_variables = "";
-					$wrappers_create = "";
-					$wrappers_release = "";
-					$variable_list = "";
-					
-					foreach ($selector["method"]["param_array"] as $pair) {
-						if (in_array($pair["type"], $this->cocoa_classes)) {
-							
-							$wrappers_variables .= "object_".$pair["name"].": ".$pair["type"].";\n";
-							$wrappers_create .= "object_".$pair["name"]." := ".$pair["type"].".CreateWithHandle(".$pair["name"].");\n";
-							$wrappers_release .= "object_".$pair["name"].".release;\n";
-							$variable_list .= "object_".$pair["name"].", ";
-						} else {
-							$variable_list .= $pair["name"].", ";
-						}
-					}
-					$variable_list = trim($variable_list, ", ");
-					
-					$template = str_replace("[VARIABLES]", $wrappers_variables, $template);
-					$template = str_replace("[WRAPPERS_CREATE]", $wrappers_create, $template);
-					$template = str_replace("[WRAPPERS_RELEASE]", $wrappers_release, $template);
-					
-					$template = str_replace("[PARAMS_LIST_WRAPPER]", "($variable_list)", $template);
-					
-					$params = $this->MakeObjcTypeParamList($selector["method"]["param_array"], false);
-					$template = str_replace("[PARAMS_LIST]", "($params)", $template);
-					
-				} else {
-					$template = str_replace("[PARAMS_HEADER]", "(_self: $this->objc_id_real; _cmd: SEL)", $template);
-					$template = str_replace("[PARAMS_LIST]", "", $template);
-					$template = str_replace("[PARAMS_LIST_WRAPPER]", "", $template);
-					$template = str_replace("[VARIABLES]", "", $template);
-					$template = str_replace("[WRAPPERS_CREATE]", "", $template);
-					$template = str_replace("[WRAPPERS_RELEASE]", "", $template);
-				}
-				
-				$this->PrintOutput(0, "");
-				$this->PrintOutput(0, $template);
-			}
-			
-			// add methods
-			foreach ($selectors as $selector) {
-				
-				// FPC long name bug work-around
-				if (strlen($selector["name_pascal"]) > $this->maximum_method_length) continue;
-				
-				$template = $this->template_method_add_runtime;
-				
-				$template = str_replace("[CLASS]", $this->master_delegate_class, $template);
-				$template = str_replace("[NAME]", $selector["name_pascal"], $template);
-				$template = str_replace("[TYPES]", $selector["types"], $template);
-				$template = str_replace("[OBJC_METHOD]", $selector["name"], $template);
-				
-				$this->PrintOutput(0, "");
-				$this->PrintOutput(0, $template);
-			}			
-		}
-		
-		$this->PrintOutput(0, "");
-		$this->PrintOutput(0, "{\$endif}");
-		
-		print("* Printed delegate class to "."$this->root$this->out/foundation/$this->master_delegate_file.inc\n");
-	}
-	
-	// Prints all externally defined symbols
-	function PrintExternalSymbols ($header) {
-		if (!$this->dump[$header["name"]]["types"]) return;
-		foreach ($this->dump[$header["name"]]["types"] as $key => $type_array) {
-			
-			// External string constants
-			if ($key == "string_constant") {
-				$this->PrintOutput(0, "");
-				$this->PrintOutput(0, "{ External string constants }");
-				$this->PrintOutput(0, "var");
-				
-				foreach ($type_array as $type) $this->PrintOutput(1, $type);
-			}
-				
-			if ($key == "external_symbol") {
-				$this->PrintOutput(0, "");
-				$this->PrintOutput(0, "{ External symbols }");
-				$this->PrintOutput(0, "var");
-				
-				foreach ($type_array as $type) $this->PrintOutput(1, $type);
-			}
-		}
-	}
-	
-	// Prints all types in the header
-	function PrintTypes ($header) {
-		if (!$this->dump[$header["name"]]["types"]) return;
-		
-		foreach ($this->dump[$header["name"]]["types"] as $key => $type_array) {	
-			
-			// External defines
-			if ($key == "defines") {
-				$this->PrintOutput(0, "");
-				$this->PrintOutput(0, "{ Defines }");
-				$this->PrintOutput(0, "const");
-				
-				foreach ($type_array as $type) $this->PrintOutput(1, $type);
-			}
-				
-			// External CFString constants
-			/*
-			if ($key == "string_constant") {
-				$this->PrintOutput(0, "");
-				$this->PrintOutput(0, "{ External string constants }");
-				$this->PrintOutput(0, "var");
-				
-				foreach ($type_array as $type) $this->PrintOutput(1, $type);
-			}
-			*/	
-							
-			// Named Enumerations
-			/*
-			if ($key == "named_enums") {
-				$this->PrintOutput(0, "");
-				$this->PrintOutput(0, "{ Sets }");
-				foreach ($type_array as $type) {
-					$this->PrintOutput(0, "");
-					$this->PrintOutput(0, "type");
-					$this->PrintOutput(1, $type);
-				}
-			}
-			*/
-			
-			// Enumerations
-			if ($key == "enums") {
-				$this->PrintOutput(0, "");
-				$this->PrintOutput(0, "{ Constants }");
-				foreach ($type_array as $block) {
-					$this->PrintOutput(0, "");
-					$this->PrintOutput(0, "const");
-					foreach ($block as $type) $this->PrintOutput(1, $type);
-				}
-			}
-			
-			// Typedefs		
-			if (($key == "typedef") || ($key == "named_enums")) {
-				$this->PrintOutput(0, "");
-				$this->PrintOutput(0, "{ Types }");
-				$this->PrintOutput(0, "type");
-
-				foreach ($type_array as $type) $this->PrintOutput(1, $type);
-			}
-			
-			// CallBacks
-			if ($key == "callbacks") {
-				$this->PrintOutput(0, "");
-				$this->PrintOutput(0, "{ Callbacks }");
-				$this->PrintOutput(0, "type");
-
-				foreach ($type_array as $name => $type) $this->PrintOutput(1, "$name = $type");
-			}
-			
-		}
-	}
-	
-	// Prints all records in the header
-	function PrintRecords ($header) {
-		if (!$this->dump[$header["name"]]["types"]) return;
-		
-		foreach ($this->dump[$header["name"]]["types"] as $key => $type_array) {			
-			// Structures
-			if ($key == "structs") {
-				$this->PrintOutput(0, "");
-				$this->PrintOutput(0, "{ Records }");
-
-				foreach ($type_array as $type) {
-					$this->PrintOutput(0, "type");
-					$this->PrintOutput(1, $type);
-				}
-			}			
-		}
-	}
-	
-	// Prints all callbacks in the header
-	function PrintCallBacks ($header) {
-		if (!$this->dump[$header["name"]]["types"]) return;
-		
-		foreach ($this->dump[$header["name"]]["types"] as $key => $type_array) {	
-			if ($key == "callbacks") {
-				$this->PrintOutput(0, "");
-				$this->PrintOutput(0, "{ Callbacks }");
-				$this->PrintOutput(0, "type");
-
-				foreach ($type_array as $name => $type) $this->PrintOutput(1, "$name = $type");
-			}
-		}
-	}
-	
-	// Prints all external functions in the header
-	function PrintFunctions ($header) {
-		if (!$this->dump[$header["name"]]["types"]) return;
-		
-		foreach ($this->dump[$header["name"]]["types"] as $key => $type_array) {	
-			if ($key == "functions") {
-				$this->PrintOutput(0, "");
-				$this->PrintOutput(0, "{ Functions }");
-				
-				foreach ($type_array as $type) $this->PrintOutput(0, $type);
-			}
-		}
-	}
-		
-	// Prints all classes from the header in reference format (not for compiling)
-	function PrintHeaderReference ($header, $path) {
-		
-		$this->output = fopen($path, "w+");
-		
-		//$this->PrintOutput(0, "{ ".ucfirst($header["framework"]).".framework ".$header["name"]." }");
-		$this->PrintOutput(0, "unit ".$header["name_clean"].";");
-		$this->PrintOutput(0, "interface");
-		$this->PrintOutput(0, "uses");
-		$this->PrintOutput(1, "ctypes, objc, MacOSAll;");
-		
-		if ($header["classes"]) {
-			foreach ($header["classes"] as $class) {
-				$this->PrintOutput(0, "");
-				$this->PrintOutput(0, "type");
-				$this->PrintOutput(1, $class["name"]."Ref = ".$this->objc_id_real.";");
-				$this->PrintOutput(1, $class["name"]."Pointer = Pointer;");
-			}
-		}
-		
-		// types
-		$this->PrintTypes($header);
-		$this->PrintRecords($header);
-		$this->PrintFunctions($header);
-		$this->PrintExternalSymbols($header);
-		
-		if ($header["classes"]) {
-			
-			foreach ($header["classes"] as $class) {
-				if (in_array($class["name"], $this->cocoa_classes)) {
-					$this->PrintOutput(0, "");
-					$this->PrintOutput(0, "type");
-					
-					$this->PrintOutput(1, $class["name"]." = object(".$class["super"].")");
-
-					// print class-level methods
-					if (count($class["methods"]) > 0) {
-						$this->PrintOutput(0, "");
-						foreach ($class["methods"] as $method) {
-							$this->PrintOutput(2, $method["def"]);
-						}
-					}
-
-					// print category-level methods
-					if (count($class["categories"]) > 0) {
-						foreach ($class["categories"] as $name => $category) {
-							$this->PrintOutput(0, "");
-							$this->PrintOutput(2, "{ Category: $name }");
-
-							if ($category["methods"]) {
-								foreach ($category["methods"] as $method) {
-									$this->PrintOutput(2, $method["def"]);
-								}
-							}	
-						}
-					}
-					
-					$this->PrintOutput(1, "end;");
-				}
-			}
-		}
-		
-		// print procedural protocols
-		if ($header["protocols"]) {
-			foreach ($header["protocols"] as $protocol) {
-				if ($protocol["methods"]) {
-					$this->PrintOutput(0, "");
-					$this->PrintOutput(0, "{ Protocol: ".$protocol["name"]." }");
-
-					foreach ($protocol["methods"] as $name => $method) {
-						if ($method["kind"] != "constructor") {
-							$this->PrintProtocolDeclaration($protocol, $method);
-						}
-					}
-				}
-			}
-		}
-		
-		$this->PrintOutput(0, "");
-		$this->PrintOutput(0, "implementation");
-		$this->PrintOutput(0, "end.");
-	}
-		
-	// Prints all classes from the header
-	public function PrintHeader ($header) {
-		global $version;
-		
-		$this->output = fopen($header["path"], "w+");
-		
-		$this->PrintOutput(0, "{ Parsed from ".ucfirst($header["framework"]).".framework ".$header["name"]." }");
-		
-		$date = date("D M j G:i:s T Y");
-		$this->PrintOutput(0, "{ Version $version - $date }");
-		$this->PrintOutput(0, "");
-		
-		$macro = strtoupper(substr($header["name"], 0, (strripos($header["name"], "."))));
-		
-		if ($header["classes"]) {
-			$this->PrintOutput(0, "{\$ifdef HEADER}");
-			$this->PrintOutput(0, "{\$ifndef $macro"."_PAS_H}");
-			$this->PrintOutput(0, "{\$define $macro"."_PAS_H}");
-		
-		
-				foreach ($header["classes"] as $class) {
-					$this->PrintOutput(0, "type");
-
-					// Make a id "reference" to each class which is an object but reveals the name of the class
-					if ($class["name"]."Ref" == $this->objc_id_real) {
-						$ref = $this->objc_id_base;	// replace duplicates with the "base id"
-					} else {
-						$ref = $this->objc_id_real;
-					}
-					
-					$this->PrintOutput(1, $class["name"]."Ref = ".$ref.";");
-
-					// Make a pointer to each class
-					$this->PrintOutput(1, $class["name"]."Pointer = Pointer;");
-				}
-		
-			$this->PrintOutput(0, "");
-			$this->PrintOutput(0, "{\$endif}");
-			$this->PrintOutput(0, "{\$endif}");
-		}
-		
-		$this->PrintOutput(0, "");
-		$this->PrintOutput(0, "{\$ifdef TYPES}");
-		$this->PrintOutput(0, "{\$ifndef $macro"."_PAS_T}");
-		$this->PrintOutput(0, "{\$define $macro"."_PAS_T}");
-		$this->PrintTypes($header);
-		$this->PrintOutput(0, "");
-		$this->PrintOutput(0, "{\$endif}");
-		$this->PrintOutput(0, "{\$endif}");
-		
-		$this->PrintOutput(0, "");
-		$this->PrintOutput(0, "{\$ifdef RECORDS}");
-		$this->PrintOutput(0, "{\$ifndef $macro"."_PAS_R}");
-		$this->PrintOutput(0, "{\$define $macro"."_PAS_R}");
-		$this->PrintRecords($header);
-		$this->PrintOutput(0, "");
-		$this->PrintOutput(0, "{\$endif}");
-		$this->PrintOutput(0, "{\$endif}");
-		
-		$this->PrintOutput(0, "");
-		$this->PrintOutput(0, "{\$ifdef FUNCTIONS}");
-		$this->PrintOutput(0, "{\$ifndef $macro"."_PAS_F}");
-		$this->PrintOutput(0, "{\$define $macro"."_PAS_F}");
-		$this->PrintFunctions($header);
-		$this->PrintOutput(0, "");
-		$this->PrintOutput(0, "{\$endif}");
-		$this->PrintOutput(0, "{\$endif}");
-		
-		$this->PrintOutput(0, "");
-		$this->PrintOutput(0, "{\$ifdef CALLBACKS}");
-		$this->PrintOutput(0, "{\$ifndef $macro"."_PAS_F}");
-		$this->PrintOutput(0, "{\$define $macro"."_PAS_F}");
-		$this->PrintCallBacks($header);
-		$this->PrintOutput(0, "");
-		$this->PrintOutput(0, "{\$endif}");
-		$this->PrintOutput(0, "{\$endif}");
-		
-		$this->PrintOutput(0, "");
-		$this->PrintOutput(0, "{\$ifdef EXTERNAL_SYMBOLS}");
-		$this->PrintOutput(0, "{\$ifndef $macro"."_PAS_T}");
-		$this->PrintOutput(0, "{\$define $macro"."_PAS_T}");
-		$this->PrintExternalSymbols($header);
-		$this->PrintOutput(0, "");
-		$this->PrintOutput(0, "{\$endif}");
-		$this->PrintOutput(0, "{\$endif}");
-		
-		if ($header["classes"]) {
-			$this->PrintOutput(0, "");
-			$this->PrintOutput(0, "{\$ifdef FORWARD}");
-		
-			foreach ($header["classes"] as $class) {
-				// if the class contains methods make a forward declaration, otherwise a dummy class to NSObject
-				if (count($class["all"]) > 0) {
-					$this->PrintOutput(1, $class["name"]." = class;");
-				} else {
-					$this->PrintOutput(1, $class["name"]." = NSObject;");
-				}
-			}
-
-			$this->PrintOutput(0, "");
-			$this->PrintOutput(0, "{\$endif}");
-		}
-	
-		if ($header["classes"]) {
-			$this->PrintOutput(0, "");
-			$this->PrintOutput(0, "{\$ifdef CLASSES}");
-			$this->PrintOutput(0, "{\$ifndef $macro"."_PAS_C}");
-			$this->PrintOutput(0, "{\$define $macro"."_PAS_C}");
-		
-			foreach ($header["classes"] as $class) {
-				if (in_array($class["name"], $this->cocoa_classes)) {
-					$this->PrintClass($class);
-					//print("	- Printed class ".$class["name"]."\n");
-				}
-			}
-	
-			$this->PrintOutput(0, "");
-			$this->PrintOutput(0, "{\$endif}");
-			$this->PrintOutput(0, "{\$endif}");
-		}
-		
-		$this->PrintOutput(0, "");
-		$this->PrintOutput(0, "{\$ifdef PROTOCOLS}");
-		$this->PrintOutput(0, "{\$ifndef $macro"."_PAS_P}");
-		$this->PrintOutput(0, "{\$define $macro"."_PAS_P}");
-		$this->PrintHeaderProtocols($header, false);
-		$this->PrintOutput(0, "");
-		$this->PrintOutput(0, "{\$endif}");
-		$this->PrintOutput(0, "{\$endif}");
-		
-		$this->PrintOutput(0, "");
-		$this->PrintOutput(0, "{\$ifdef IMPLEMENTATION}");
-	
-		$this->PrintHeaderProtocols($header, true);
-		
-		if ($header["classes"]) {
-			foreach ($header["classes"] as $class) {
-				if (in_array($class["name"], $this->cocoa_classes)) {
-					$this->PrintClassImplementation($class);
-				}
-			}
-		}
-		
-		$this->PrintOutput(0, "{\$endif}");
-	}
-
-	// Prints all headers parsed
-	function PrintAllHeaders ($output_path, $ignore_output, $only_files, $print_header_references) {
-			
-			foreach ($this->dump as $file => $header) {
-				if (eregi("^[a-zA-Z]+\.h", $file)) {
-					
-					// ignore these files
-					if (@in_array($header["path_partial"], $ignore_output)) continue;
-					
-					// only parse these files
-					if ((@count($only_files) > 0) && (@!in_array($header["name"], $only_files))) continue;
-					
-					$name_clean = substr($file, 0, (strripos($file, ".")));	
-					
-					// assign output path
-					if ($output_path != "") $header["path"] = $output_path."/".$name_clean.".inc";
-					
-					$this->PrintHeader($header);
-					
-					if ($print_header_references) $this->PrintHeaderReference($header, $this->root.$this->out."/reference/".$name_clean.".pas");
-					
-					print("* Printed $name_clean.h to ".$header["path"]."\n");
-				}
-			}
-	}	
-	
-	/**
-	 * PARSING METHODS
-	 */
-	
-	// Insert macro blocks to replace c-style blocks
-	function InsertMacroBlocks ($line, &$in_macro_block) {
-		
-		// only insert if we are in a block already.
-		// NOTE: this does not handle nesting!
-		if ($in_macro_block) {
-			
-			// macro else statment
-			if (eregi("#else", $line)) {
-				return "{\$else}";
-			}
-
-			// macro endif statment
-			if (eregi("#endif", $line)) {
-				$in_macro_block = false;
-				return "{\$endif}";
-			}
-		}
-		
-		foreach ($this->macro_blocks as $key => $value) {
-			if (eregi($key, $line, $captures)) {
-				$in_macro_block = true;
-				
-				// replace the c-macro with a Pascal version
-				if ($value == "*") {
-					$captures[0] = trim($captures[0], "#");
-					return "{\$".$captures[0]."}";
-				} else {
-					return "{".$value."}";
-				}
-			}
-		}
-	}
-
-	function ParseInstanceVariables ($line, &$struct) {
-		$field = null;
-		$field_bitpacked = false;
-		//print("$line\n");
-			
-		// insert macros
-		if ($macro = $this->InsertMacroBlocks($line, $this->inside_macro_block)) {
-			if ($struct["valid"]) {
-				$struct["fields"][] = $macro;
-				return null;
-			} else {
-				return $macro;
-			}
-			
-		}
-		// got struct
-		if (eregi("^[[:space:]]*struct.*{", $line)) {
-			$struct["valid"] = true;
-			return null;
-		} 
-		
-		if (eregi("^[[:space:]]*}[[:space:]]*([a-zA-Z_0-9]+);", $line, $captures)) {
-			$struct["name"] = "_".trim($captures[1], " 	");
-			//print_r($struct);
-			return "struct";
-		}
-		
-		// set field prefix to protect scope
-		if (!$struct["valid"]) $field_prefix = "_";
-		
-		// remove null-defined macros: 
-		$line = str_ireplace($this->null_macros, "", $line);
-		
-		// replace garbage collector hints in the field	
-		$line = $this->ReplaceGarbageCollectorHints($line, $garbage_collector_hint);
-				
-		if (ereg("^[[:space:]]*([a-zA-Z0-9_]+)[[:space:]]+([a-zA-Z0-9_]+)[[:space:]]+([a-zA-Z0-9_*	 ]+).*;", $line, $captures)) { // double-word single
-			
-			$name = trim($captures[3], "* 	");
-			$name = str_replace(" ", "", $name);
-			$name = str_replace("	", "", $name);
-
-			if (eregi("^[[:space:]]*struct", $captures[1])) {
-				$type = $captures[2];
-			} else {
-				$type = $captures[1]." ".$captures[2];
-			}
-			
-			$type = $this->ReplaceObjcType($type);
-			$type = $this->SwapObjcTypeWithReal($type);
-			$type = $this->MakeFieldBitPacked($type, $line, $field_bitpacked);
-			if ($this->IsKeywordReserved($name)) $name .= "_";
-			if ($captures[3][0] == "*") $this->ReplacePointerType($type);
-
-			$field = "$field_prefix$name: $type;";
-			$field = $this->MakeFieldInlineArray($field, $line, $name, $type);
-			$field = eregi_replace("<.*>", "", $field);
-			
-		} elseif (ereg("^[[:space:]]*([a-zA-Z0-9_]+)[[:space:]]+([a-zA-Z0-9_* 	]+)(.*);", $line, $captures)) { // double-word type list
-			$name = trim($captures[2], "* 	");
-			$name = str_replace(" ", "", $name);
-			$name = str_replace("	", "", $name);
-			
-			$type = $this->ReplaceObjcType($captures[1]);
-			$type = $this->SwapObjcTypeWithReal($type);
-			$type = $this->MakeFieldBitPacked($type, $line, $field_bitpacked);
-			if ($this->IsKeywordReserved($name)) $name .= "_";
-			if ($captures[2][0] == "*") $this->ReplacePointerType($type);
-			
-			$field = "$field_prefix$name: $type;";
-			$field = $this->MakeFieldInlineArray($field, $line, $name, $type);
-			$field = eregi_replace("<.*>", "", $field);
-			
-		} elseif (ereg("^[[:space:]]*([a-zA-Z0-9_*]+)(.*);", $line, $captures)) { // single word type list
-			$name = trim($captures[2], "* 	");
-			$name = str_replace(" ", "", $name);
-			$name = str_replace("	", "", $name);
-
-			$type = $this->ReplaceObjcType($captures[1]);
-			$type = $this->SwapObjcTypeWithReal($type);
-			$type = $this->MakeFieldBitPacked($type, $line, $field_bitpacked);
-			if ($this->IsKeywordReserved($name)) $name .= "_";
-			if ($captures[2][0] == "*") $this->ReplacePointerType($type);
-			$type = trim($type, "*");
-
-			$field = "$field_prefix$name: $type;";
-			$field = $this->MakeFieldInlineArray($field, $line, $name, $type);
-			$field = eregi_replace("<.*>", "", $field);
-		}
-		
-		// mark the field as having a garbage collector field
-		if ($garbage_collector_hint) $field = "$field {garbage collector: $garbage_collector_hint }";
-		
-		// return field
-		if ($struct["valid"]) {
-			if ($field_bitpacked) $struct["bitpacked"] = true;
-			$struct["fields"][] = $field;
-		} else {
-			return $field;
-		}
-	}
-	
-	// Parses a struct field into a list
-	function ParseStructList ($input, $name, $type) {
-		$field = "";
-		
-		$list = explode(",", $input);
-		if (count($list) > 1) {
-			$field = "    ";
-			foreach ($list as $key) {
-				$key = trim($key, " ");
-				$field .= "$key, ";
-			}
-			
-			$field = rtrim($field, ", ");
-			$field .= ": $type;\n";
-		} else {
-			$field = "    $name: $type;\n";
-		}
-		
-		return $field;
-	}
-	
-	// Parse external symbols, enums and typedef's from the header
-	function ParseHeaderTypes ($file) {
-			$contents = ReadTextFile($file);
-			$file_name = substr($file, (strripos($file, "/")) + 1, strlen($file));	
-			$field_bitpacked = false;
-			
-			$lines = explode("\n", $contents);
-			foreach ($lines as $line) {
-				
-				// skip blocks
-				if ($this->SkipBlock($line)) continue;
-				
-				// garbage collector hints
-				$line = $this->ReplaceGarbageCollectorHints($line, $garbage_collector_hint);
-					
-				// remove macros	
-				$line = $this->RemoveOSVersionMacros($line);
-				
-				// remove comments
-				$line = $this->RemoveComments($line);
-				$line = trim($line, " ");
-									
-				if ($got_struct) {
-					
-					// insert macros
-					if ($macro = $this->InsertMacroBlocks($line, $this->inside_macro_block)) $struct_fields .= "$macro\n";
-					
-					// collect fields
-					if (eregi("^[[:space:]]*([a-zA-Z0-9_*]+)[[:space:]]*[*]*\((.*)\)\((.*)\);", $line, $captures)) { // function pointer (callback)
-						//continue;
-						$name = trim($captures[2], "*");
-						$result = $this->ReplaceNSTypesWithReal($captures[1]);
-						$result = $this->ReplaceObjcType($result);
-						$result = ": ".$this->SwapObjcTypeWithReal($result);
-						if ($this->IsKeywordReserved($name)) $name .= "_";
-						
-						if ($captures[1] == "void") {
-							$kind = "procedure";
-							$result = "";
-						} else {
-							$kind = "function";
-						}
-						
-						// ??? convert params to Pascal
-						//$method = $this->ConvertFunctionPointerToPascal($result, $captures[3]);
-						//$params = $method["param_string_clean"];
-						$params = "context: Pointer {bad params!!}";
-						
-						$struct_fields .= "    $name: $kind ($params)$result; cdecl;\n";
-						//print("$name: $kind ($params)$result; cdecl;\n");
-					} elseif (ereg("^[[:space:]]*([a-zA-Z0-9_]+)[[:space:]]+([a-zA-Z0-9_]+)[[:space:]]+([a-zA-Z0-9_* 	]+)(.*);", $line, $captures)) { // double-word single
-						$name = trim($captures[3], "* ");
-						$name = str_replace(" ", "", $name);
-						$name = str_replace("	", "", $name);
-						$type = $captures[1]." ".$captures[2];
-						$type = $this->ReplaceObjcType($type);
-						$type = $this->SwapObjcTypeWithReal($type);
-						$type = $this->MakeFieldBitPacked($type, $line, $field_bitpacked);
-						if ($this->IsKeywordReserved($name)) $name .= "_";
-						if ($captures[3][0] == "*") $this->ReplacePointerType($type);
-						
-						//$struct_fields .= "    $name: $type;\n";
-						$struct_fields .= $this->ParseStructList($captures[3]+$captures[4], $name, $type);
-						
-					} elseif (ereg("^[[:space:]]*([a-zA-Z0-9_]+)[[:space:]]+([a-zA-Z0-9_* 	]+)(.*);", $line, $captures)) { // double-word type list
-						$name = trim($captures[2], "* ");
-						$name = str_replace(" ", "", $name);
-						$name = str_replace("	", "", $name);
-						$type = $this->ReplaceObjcType($captures[1]);
-						$type = $this->SwapObjcTypeWithReal($type);
-						$type = $this->MakeFieldBitPacked($type, $line, $field_bitpacked);
-						if ($this->IsKeywordReserved($name)) $name .= "_";
-						if ($captures[2][0] == "*") $this->ReplacePointerType($type);
-						
-						$struct_fields .= $this->ParseStructList("$captures[2]$captures[3]", $name, $type);
-
-					} elseif (ereg("^[[:space:]]*([a-zA-Z0-9_* 	]+)(.*);", $line, $captures)) { // single word type list
-						$name = trim($captures[2], "* ");
-						$captures[1] = str_replace(" ", "", $captures[1]);
-						$captures[1] = str_replace("	", "", $captures[1]);
-						$type = $this->ReplaceObjcType($captures[1]);
-						$type = $this->SwapObjcTypeWithReal($type);
-						$type = $this->MakeFieldBitPacked($type, $line, $field_bitpacked);
-						if ($this->IsKeywordReserved($name)) $name .= "_";
-						if ($captures[2][0] == "*") $this->ReplacePointerType($type);
-						
-						//$struct_fields .= "    $name: $type;\n";
-						$struct_fields .= $this->ParseStructList($captures[2], $name, $type);
-					}
-
-					
-					// got end of struct
-					if (ereg("^}[[:space:]]*([a-zA-Z_0-9]+);", $line, $captures)) {
-						
-						if ($struct_name == "") {
-							$struct_name = $captures[1];
-							$make_pointer = true;
-						} else {
-							$struct_type = $captures[1];
-						}
-						
-						if ($field_bitpacked) {
-							$struct = "$struct_name = $this->bitpacked_record_keyword\n";
-						} else {
-							$struct = "$struct_name = $this->record_keyword\n";
-						}
-						
-						$struct .= $struct_fields;
-						$struct .= "  end;\n";
-						if (($struct_type) && ($struct_name != $struct_type)) {
-							$struct .= "$struct_type = $struct_name;\n";
-							// SEE NOTE BELOW
-							//$struct .= $struct_type."Pointer = ^$struct_type;\n";
-							$make_pointer = false;
-						}
-						
-						// make an extra pointer for us since Pascal may need it
-						// NOTE: remove this until we can protect against duplicate types
-						//if ($make_pointer) $struct .= $struct_name."Pointer = ^$struct_name;\n";
-						
-						$this->dump[$file_name]["types"]["structs"][] = $struct;
-						$this->dump["global_structs"][] = $struct_name;
-						$got_struct = false;
-						$field_bitpacked = false;
-					}
-				}
-				
-				
-				// got struct
-				if (ereg("^typedef struct(.*){", $line, $captures)) {
-					
-					$struct_name = trim($captures[1], " ");
-					$struct_type = null;
-					$struct_fields = "";
-					
-					$make_pointer = false;
-					$got_struct = true;
-				}
-				
-				// integer #define
-				if (ereg("#define[[:space:]]+([a-zA-Z0-9_]+)[[:space:]]+([0-9.]+)", $line, $captures)) {
-					$this->dump[$file_name]["types"]["defines"][] = $captures[1]." = ".$captures[2].";";
-				}
-				
-				// parse enum fields
-				if (($got_enum) || ($got_named_enum)) {
-					//print($line."\n");
-					
-					// insert macros
-					//if ($macro = $this->InsertMacroBlocks($line, $this->inside_macro_block)) $this->dump[$file_name]["types"]["enums"][$block_count][] = $macro;
-
-					if (ereg("^[[:space:]]*([a-zA-Z0-9_]+)[[:space:]]*=[[:space:]]*([a-zA-Z_]+)[,]*[[:space:]]*$", $line, $captures)) { // string value
-						$captures[2] = trim($captures[2], ", ");
-						$this->dump[$file_name]["types"]["enums"][$block_count][] = $captures[1]." = ".$captures[2].";";
-					} elseif (ereg("^[[:space:]]*([a-zA-Z0-9_]+)[[:space:]]*=[[:space:]]*([0-9-]+)[,]*[[:space:]]*$", $line, $captures)) { // integer value
-						$captures[2] = trim($captures[2], ", ");
-						$this->dump[$file_name]["types"]["enums"][$block_count][] = $captures[1]." = ".$captures[2].";";
-					} elseif (ereg("^[[:space:]]*([a-zA-Z0-9_]+)[[:space:]]*=[[:space:]]*([0-9]+[xX]+[a-fA-F0-9]+)", $line, $captures)) { // hexadecimal value
-						$captures[2] = trim($captures[2], ", ");
-						$captures[2] = eregi_replace("^0x", "$", $captures[2]);
-						$this->dump[$file_name]["types"]["enums"][$block_count][] = $captures[1]." = ".$captures[2].";";
-					} elseif (ereg("^[[:space:]]*([a-zA-Z0-9_]+)[[:space:]]*=[[:space:]]*([0-9]+[[:space:]]*<<[[:space:]]*[0-9]+)", $line, $captures)) { // << shl value, no ()
-						$captures[2] = str_replace("<<", " shl ", $captures[2]);
-						$this->dump[$file_name]["types"]["enums"][$block_count][] = $captures[1]." = ".$captures[2].";";
-					} elseif (ereg("^[[:space:]]*([a-zA-Z0-9_]+)[[:space:]]*=[[:space:]]*\(([0-9]+[[:space:]]*<<[[:space:]]*[0-9]+)\)", $line, $captures)) { // << shl value
-						$captures[2] = trim($captures[2], ", ");
-						$captures[2] = str_replace("<<", " shl ", $captures[2]);
-						$this->dump[$file_name]["types"]["enums"][$block_count][] = $captures[1]." = ".$captures[2].";";
-					} elseif (ereg("^[[:space:]]*([a-zA-Z0-9_]+)[[:space:]]*[,}]*[[:space:]]*$", $line, $captures)) { // non-value
-						
-						// omit lines which started nested structures.
-						// bad practice but the single-line regex parser can't handle them
-						if (!eregi("[=|]+", $line)) {
-							$captures[1] = trim($captures[1], ", ");
-							$this->dump[$file_name]["types"]["enums"][$block_count][] = $captures[1]." = ".$auto_increment.";";
-							$auto_increment ++;
-						}
-					}
-									
-					// found the end
-					if (ereg("^};", $line)) $got_enum = false;
-				}
-				
-				// ==== got enum ===
-				if (ereg("^enum {", $line)) {
-					$got_enum = true;
-					$block_count ++;
-					$auto_increment = 0;
-				}
-				
-				// terminate named enum
-				if ($got_named_enum) {
-					if (ereg("^}[[:space:]]*([a-zA-Z0-9_]+);", $line, $captures)) {
-						$got_named_enum = false;
-						
-						$named_enum = trim($named_enum, ", \n");
-						
-						$this->dump[$file_name]["types"]["named_enums"][] = "$captures[1] = culong;";
-						$this->dump["global_types"][$captures[1]] = $captures[1];
-					}
-				}
-				
-				// ==== got named enum ===
-				if (ereg("^typedef enum {", $line)) {
-					$got_named_enum = true;
-					$named_enum = "";
-					$auto_increment = 0;
-					$block_count ++;
-				}
-				
-				// ==== external string constant ===
-				if (eregi("^($this->external_string_macros)+[[:space:]]+NSString[[:space:]]+\*[[:space:]]*(const)*[[:space:]]*([a-zA-Z_]+);", $line, $captures)) {
-					$name = $captures[3];
-					
-					if (in_array($name, $this->ignore_symbol)) continue;
-					
-					$this->dump[$file_name]["types"]["string_constant"][] = "$name: $this->string_macro; external name '_$name';";
-				}
-				
-				// ==== external symbol ===
-				if (eregi("^($this->external_string_macros)+[[:space:]]+([a-zA-Z_ ]+)[[:space:]]+([a-zA-Z_]+);", $line, $captures)) {
-					$name = $captures[3];
-					$type = $captures[2];
-
-					// ignore symbols
-					if (in_array($name, $this->ignore_symbol)) continue;
-					
-					$type = istr_replace_word("const", "", $type);
-					$type = trim($type, " ");
-					
-					$this->dump[$file_name]["types"]["external_symbol"][] = "$name: $type; external name '_$name';";
-				}
-				
-				
-				// ==== external procedures ===
-				if (ereg("^($this->external_string_macros)+[[:space:]]+(.*)[[:space:]]+(\*)*([a-zA-Z0-9_]+)\((.*)\)", $line, $captures)) {
-					
-					$result = $this->ConvertReturnType($captures[2]);
-					$name = $captures[4];
-					$params = "";
-					$captures[2] = trim($captures[2], " 	");
-					$captures[5] = trim($captures[5], " 	");
-
-					// ignore symbols
-					if (in_array($name, $this->ignore_symbol)) continue;
-					
-					if ($captures[5] != "void") $params = "(".$this->ConvertCParamsPascal($captures[5]).")";
-					
-					if ($captures[2] == "void") {
-						$this->dump[$file_name]["types"]["functions"][] = "procedure $name$params; cdecl; external name '$name';";
-					} else {
-						$this->dump[$file_name]["types"]["functions"][] = "function $name$params: $result; cdecl; external name '$name';";
-					}
-				}
-				
-				// ==== got typedef ===
-				if (ereg("^typedef[[:space:]]+struct[[:space:]]+([a-zA-Z0-9_]+)[[:space:]]+([a-zA-Z0-9_]+);", $line, $captures)) { // defined struct type
-					$real_type = $captures[1];
-					$struct_type = $captures[1];
-					$new_type = $captures[2];
-					
-					$this->AddTypeDef($this->dump[$file_name], "$struct_type = Pointer;");
-					
-					$struct_type = $this->ReplaceObjcType($struct_type);
-					$struct_type = $this->SwapObjcTypeWithReal($struct_type);
-					$this->AddTypeDef($this->dump[$file_name], "$new_type = $struct_type;");
-					
-					$this->dump["global_types"][$struct_type] = "Pointer";
-					$this->dump["global_types"][$new_type] = $real_type;
-				} elseif (ereg("^typedef[[:space:]]+struct[[:space:]]+([a-zA-Z0-9_]+)[[:space:]]+([a-zA-Z0-9_*]+);", $line, $captures)) { // pointer to struct
-					$real_type = $captures[1];
-					$clean_name = trim($captures[2], "*");
-					$pointer_type = $captures[1];
-					
-					// ??? maybe check to see if this type exists like NSRect *NSRect is NSRectPointer which exists
-					$pointer_type = "Pointer";
-						
-					//$captures[2] = $this->FormatObjcType($captures[2], $modifiers);
-					//$this->dump[$file_name]["types"]["typedef"][] = "$pointer_type = Pointer;";
-					$this->AddTypeDef($this->dump[$file_name], "$clean_name = $pointer_type;");
-					
-					
-					//$this->dump["global_types"][$pointer_type] = "Pointer";
-					$this->dump["global_types"][$clean_name] = $real_type;
-				} elseif (ereg("^typedef[[:space:]]+(const)*[[:space:]]*struct[[:space:]]+([a-zA-Z0-9_*]+)[[:space:]]+([a-zA-Z0-9_]+);", $line, $captures)) { // struct type (complex)
-					$real_type = $captures[1];
-					
-					$captures[2] = $this->FormatObjcType($captures[2], $modifiers);
-					$this->AddTypeDef($this->dump[$file_name], $captures[3]." = ".$captures[2].";");
-					
-					$this->dump["global_types"][$captures[3]] = $real_type;
-				} elseif (ereg("^typedef[[:space:]]+([a-zA-Z0-9_]+)[[:space:]]+([a-zA-Z0-9_*]+);", $line, $captures)) { // single-word type
-					$real_type = $captures[1];
-					
-					// type is a pointer
-					if ($captures[2][0] == "*") {
-						$captures[2] = trim($captures[2], "*");
-						$captures[1] = $this->ReplaceObjcType($captures[1]);
-						$captures[1] = $this->SwapObjcTypeWithReal($captures[1]);
-						$this->AddTypeDef($this->dump[$file_name], $captures[2]." = ^".$captures[1].";");
-						
-						$this->dump["global_types"][$captures[2]] = $real_type;
-					} else {
-						$captures[2] = trim($captures[2], "*");
-						$captures[1] = $this->ReplaceObjcType($captures[1]);
-						$captures[1] = $this->SwapObjcTypeWithReal($captures[1]);
-						$this->AddTypeDef($this->dump[$file_name],$captures[2]." = ".$captures[1].";");
-
-						$this->dump["global_types"][$captures[2]] = $real_type;
-					}
-				} elseif (ereg("^typedef[[:space:]]+([a-zA-Z0-9_]+)[[:space:]]+([a-zA-Z0-9_]+)[[:space:]]+([a-zA-Z0-9_*]+);", $line, $captures)) { // double-word type
-					$real_type = $captures[1];
-					
-					$captures[3] = trim($captures[3], "*");
-					$long_type = $captures[1]." ".$captures[2];
-					$long_type = $this->ReplaceObjcType($long_type);
-					$long_type = $this->SwapObjcTypeWithReal($long_type);
-					$this->AddTypeDef($this->dump[$file_name], $captures[3]." = $long_type;");
-					
-					$this->dump["global_types"][$captures[3]] = $real_type;
-				}
-			}
-			
-		//print_r($this->dump[$file_name]["types"]);
-	}	
-	
-	// Parse all protocols in a header
-	function ParseHeaderProtocols ($file) {
-			$contents = ReadTextFile($file);
-			$file_name = substr($file, (strripos($file, "/")) + 1, strlen($file));
-			
-			$lines = explode("\n", $contents);
-			foreach ($lines as $line) {
-							
-				// parse protocol
-				if ($got_protocol) {
-					
-					// remove comments
-					$line = $this->RemoveComments($line);
-					
-					// found property
-					if (eregi($this->regex_objc_property, $line, $captures)) {
-							$property = $this->ParseClassProperty($current_protocol, $captures);
-							
-							if ($property["setter"]) {
-								$this->current_header["protocols"][$current_protocol]["methods"][$method["objc_method"]] = $property["setter"];
-							}
-							
-							if ($property["getter"]) {
-								$this->current_header["protocols"][$current_protocol]["methods"][$method["objc_method"]] = $property["getter"];
-							}
-							
-							continue;
-					}
-					
-					// found method
-					$method = null;
-					if (eregi($this->regex_objc_method_params, $line, $captures)) {
-						$method = $this->ConvertObjcMethodToPascal($current_protocol, $line, $captures, array(), true);	
-					} elseif (eregi($this->regex_objc_method_no_params, $line, $captures)) {
-						$method = $this->ConvertObjcMethodToPascal($current_protocol, $line, $captures, array(), false);
-					}
-
-					// append to classes
-					if (($method) && (!in_array($current_protocol, $this->ignore_categories)) && (!in_array($method["name"], $this->ignore_methods)) ) {
-						$this->current_header["protocols"][$current_protocol]["methods"][$method["objc_method"]] = $method;
-					}
-					
-					// found the end
-					if (ereg("^@end", $line)) $got_protocol = false;
-				}
-				
-				// got protocol
-				if ((eregi($this->regex_objc_protocol, $line, $captures)) && (!eregi(".*;$", $line))) {
-						$got_protocol = true;
-						$current_protocol = $captures[1];
-						print("+ Protocol $current_protocol\n");
-						$this->current_header["protocols"][$current_protocol]["name"] = $captures[1];
-				}
-			}
-			
-		//print_r($this->current_class);
-	}
-	
-	
-	// Parse all categories in a header
-	function ParseHeaderCategories ($file) {
-			$contents = ReadTextFile($file);
-			$file_name = substr($file, (strripos($file, "/")) + 1, strlen($file));
-			
-			$lines = explode("\n", $contents);
-			foreach ($lines as $line) {
-							
-				// parse category
-				if ($got_category) {
-					
-					// remove comments
-					$line = $this->RemoveComments($line);
-					
-					// found property
-					if (eregi($this->regex_objc_property, $line, $captures)) {
-							$property = $this->ParseClassProperty($current_category, $captures);
-							
-							if ($property["setter"]) {
-								if ($this->AddMethodToClass($property["setter"], $this->current_class)) {
-									$this->dump[$category_owner]["classes"][$current_class]["categories"][$current_category]["methods"][] = $property["setter"];
-								}
-							}
-							
-							if ($property["getter"]) {
-								if ($this->AddMethodToClass($property["getter"], $this->current_class)) {
-									$this->dump[$category_owner]["classes"][$current_class]["categories"][$current_category]["methods"][] = $property["getter"];
-								}
-							}
-
-							continue;
-					}
-					
-					// found method
-					$method = null;
-					if (eregi($this->regex_objc_method_params, $line, $captures)) {
-						$method = $this->ConvertObjcMethodToPascal($current_category, $line, $captures, $this->GetProtectedKeywords($this->current_class), true);						
-					} elseif (eregi($this->regex_objc_method_no_params, $line, $captures)) {
-						$method = $this->ConvertObjcMethodToPascal($current_category, $line, $captures, $this->GetProtectedKeywords($this->current_class), false);	
-					}
-					
-					// append to classes
-					if (($method) && (!in_array($method["name"], $this->ignore_categories))) {
-						if ($current_class) {
-							if ($this->AddMethodToClass($method, $this->current_class)) {
-								$this->dump[$category_owner]["classes"][$current_class]["categories"][$current_category]["methods"][] = $method;
-							}
-						} else {
-							
-							// add base categories to NSObject
-							if (in_array($current_category, $this->base_categories)) {
-								if ($this->AddMethodToClass($method, $this->dump["NSObject.h"]["classes"]["NSObject"])) {
-									$this->dump["NSObject.h"]["classes"]["NSObject"]["categories"][$current_category]["methods"][] = $method;
-								}
-							}
-							
-							$this->dump["categories"][$current_category]["methods"][$method["objc_method"]] = $method;
-						}
-					}
-					
-					// found the end
-					if (ereg("^@end", $line)) $got_category = false;
-				}
-				
-				// got category
-				if (eregi($this->regex_objc_category, $line, $captures)) {
-					
-					// ??? if the current header is NSObject, then we DO want to accept these categories, they are NOT delegates this time...
-					
-					// append category to it's super class
-					$category_owner = $this->FindCategoryHeader($captures[1]);
-					if (($category_owner) && ($captures[1] != "NSObject")) {
-						$got_category = true;
-						$current_category = $captures[2];
-						$current_class = $captures[1];
-						$this->current_class = &$this->dump[$category_owner]["classes"][$current_class];
-						
-						$this->dump[$category_owner]["classes"][$current_class]["categories"][$current_category]["name"] = $captures[2];
-						$this->dump[$category_owner]["classes"][$current_class]["categories"][$current_category]["super"] = $captures[1];
-						
-						print("	-> Category $current_category belongs to $current_class in $category_owner\n");
-					} else {
-						
-						if ($captures[1] == "NSObject") {
-							print("	+ Category ".$captures[2]."->".$captures[1]." belongs to NSObject\n");
-							$got_category = true;
-						} else {
-							$this->warning_count ++;
-							print("# WARNING: Category ".$captures[2]." (".$captures[1].") has no header\n");
-							$got_category = false;
-						}
-						
-						$current_category = $captures[2];
-						$current_class = null;
-
-						$this->dump["categories"][$current_category]["name"] = $captures[2];
-						$this->dump["categories"][$current_category]["super"] = $captures[1];
-					}
-					
-				}
-			}
-			
-		//print_r($this->current_class);
-	}
-	
-	// Parse all "pre-defined" category methods in a header
-	function PreparseCategoryMethods ($file) {
-			$contents = ReadTextFile($file);
-			$file_name = substr($file, (strripos($file, "/")) + 1, strlen($file));
-			
-			$lines = explode("\n", $contents);
-			foreach ($lines as $line) {
-							
-				// parse category
-				if ($got_category) {
-					
-					// found method
-					$method = null;
-					if (eregi($this->regex_objc_method_params, $line, $captures)) {
-						$method = $this->ConvertObjcMethodToPascal($current_category, $line, $captures, array(), true);						
-					} elseif (eregi($this->regex_objc_method_no_params, $line, $captures)) {
-						$method = $this->ConvertObjcMethodToPascal($current_category, $line, $captures, array(), false);	
-					}
-					
-					// append to classes
-					if (($method) && ($current_class)) {
-						$this->dump[$category_owner]["category_methods"][] = $method["name"];
-						//print($method["name"]."\n");
-					}
-					
-					// found the end
-					if (ereg("^@end", $line)) $got_category = false;
-				}
-				
-				// got category
-				if (eregi($this->regex_objc_category, $line, $captures)) {
-					$category_owner = $this->FindCategoryHeader($captures[1]);
-					if ($category_owner) {
-						$got_category = true;
-						$current_category = $captures[2];
-						$current_class = $captures[1];
-					} else {
-						$current_class = null;
-					}
-				}
-			}
-			
-		return $this->dump[$category_owner]["category_methods"];
-	}
-	
-	// Preparses a class for protected keywords
-	function PreparseClass ($lines, $line_count) {
-		$protected_keywords = array();
-		
-		for ($i=$line_count; $i < count($lines); $i++) { 
-			$line = $lines[$i - 1];
-			
-			// found method
-			if (eregi($this->regex_objc_method_params, $line, $captures)) {
-				$method = $this->ConvertObjcMethodToPascal($current, $line, $captures, $protected_keywords, true);						
-				$this->current_class["protected_keywords"][] = $method["name"];
-			} elseif (eregi($this->regex_objc_method_no_params, $line, $captures)) {
-				$method = $this->ConvertObjcMethodToPascal($current, $line, $captures, $protected_keywords, false);
-				$this->current_class["protected_keywords"][] = $method["name"];
-			}
-			
-			// class ended
-			if (ereg("^@end", $line)) return $protected_keywords;
-		}
-	}
-	
-	// Gets the preferred property name from attributes
-	function GetPropertyName ($kind, $params, &$name) {
-		foreach ($params as $value) {
-			$pair = explode("=", $value);
-			
-			if ($pair[0] == $kind) {
-				$name = $pair[1];
-				return true;
-				break;
-			}
-		}
-	}
-	
-	// Convert a method return type to Pascal
-	function ConvertReturnType ($type) {
-		$type = trim($type, " ");
-		$type = $this->ReplaceObjcType($type);
-
-		// if the type was not converted remove the * and process further
-		$type = trim($type, "* ");
-		$type = $this->ReplaceObjcType($type);
-
-		// format the return type again to make sure it's clean
-		$type = $this->FormatObjcType($type, $null_modifier);
-		
-		return $type;
-	}
-	
-	// Parse a property into accessor methods
-	function ParseClassProperty ($class, $parts) {
-		$property["parameters"] = explode(",", $parts[1]);
-		$method = array();
-		
-		// property name
-		if (eregi("([a-zA-Z0-9]+)$", $parts[2], $captures)) $property["name"] = ucwords($captures[1]);
-		
-		// property type
-		$type = istr_replace_word($captures[1], "", $parts[2]);
-		$type = $this->ConvertReturnType($type);
-		
-		// setter
-		if (!in_array("readonly", $property["parameters"])) {
-			$method["setter"] = array();
-			
-			$name = $property["name"];
-			if (!$this->GetPropertyName("setter", $property["parameters"], $name)) {
-				$name = "set$name";
-			}
-			
-			// protect method name from keywords
-			if ($this->IsKeywordReserved($name)) $name .= "_";
-			
-			$method["setter"]["def"] = "procedure $name (newValue: $type);";
-			$method["setter"]["objc_method"] = "$name:";
-			$method["setter"]["class"] = $class;
-			$method["setter"]["name"] = $name;
-			$method["setter"]["kind"] = "procedure";
-		}
-		
-		// getter
-		$method["getter"] = array();
-		
-		$name = $property["name"];
-		if (!$this->GetPropertyName("getter", $property["parameters"], $name)) {
-			$name = strtolower(substr($name, 0, 1)) . substr($name, 1);
-		}
-		
-		// protect method name from keywords
-		if ($this->IsKeywordReserved($name)) $name .= "_";
-		
-		$method["getter"]["def"] = "function $name: $type;";
-		$method["getter"]["objc_method"] = $name;
-		$method["getter"]["class"] = $class;
-		$method["getter"]["name"] = $name;
-		$method["getter"]["kind"] = "function";
-		
-		return $method;
-	}
-	
-	// Main entry to parse a header
-	function ParseHeaderClasses ($file) {
-			$contents = ReadTextFile($file);
-			
-			$file_name = substr($file, (strripos($file, "/")) + 1, strlen($file));
-			$line_count = 0;
-			
-			$lines = explode("\n", $contents);
-			foreach ($lines as $line) {
-				$line_count++;
-				
-				// remove external class macros
-				$line = eregi_replace("^[A-Z0-9]+_EXTERN_CLASS[[:space:]]+", "", $line);
-				
-				// parse instance vars
-				if ($got_instance_vars) {
-					
-					// scope compiler directive
-					if (eregi($this->regex_scope_compiler_directive, $line, $captures)) {
-						$this->instance_var_scope = $captures[1];
-						continue;
-					}
-					
-					// remove comments
-					$line = $this->RemoveComments($line);
-					
-					// parse instance variables
-					$result = $this->ParseInstanceVariables($line, $struct);
-					
-					// parse structures
-					if ($result == "struct") {
-						//print_r($struct);
-						//$this->dump[$file_name]["classes"][$current]["ivars"][] = $struct["name"].": $current"."_".$struct["name"].";";
-						$this->dump[$file_name]["classes"][$current]["ivars_structs"][] = $struct;
-						
-						// print inline-record type
-						if ($struct["bitpacked"]) {
-							$this->dump[$file_name]["classes"][$current]["ivars"][] = $struct["name"].": ".$this->bitpacked_record_keyword;
-						} else {
-							$this->dump[$file_name]["classes"][$current]["ivars"][] = $struct["name"].": ".$this->record_keyword;
-						}
-						
-						
-						// print fields
-						if ($struct["fields"]) {
-							foreach ($struct["fields"] as $field) $this->dump[$file_name]["classes"][$current]["ivars"][] = "    ".$field;
-						}
-						$this->dump[$file_name]["classes"][$current]["ivars"][] = "  end;";
-						
-						$struct = null;
-					} elseif($result != null) {
-						//print($result);
-						$this->dump[$file_name]["classes"][$current]["ivars"][] = $result;
-					}
-					
-					// instance var section terminated.
-					if (eregi("^\s*}\s*$", $line)) {
-						$struct = null;
-						$got_instance_vars = false;
-						$this->instance_var_scope = null;
-					}
-					
-				} elseif ($got_class) { // parse the class
-					
-					// the instance variable section started after the class line and no other ivar's were parsed yet
-					if (!$this->dump[$file_name]["classes"][$current]["ivars"]) {
-						if (eregi("{\s*$", $line)) {
-							$got_instance_vars = true;
-							continue;
-						}
-					}
-					
-					// remove comments
-					$line = $this->RemoveComments($line);
-					
-					// found property
-					if (eregi($this->regex_objc_property, $line, $captures)) {
-							$property = $this->ParseClassProperty($current, $captures);
-							
-							if ($property["setter"]) {
-								if ($this->AddMethodToClass($property["setter"], $this->dump[$file_name]["classes"][$current])) {
-									$this->dump[$file_name]["classes"][$current]["methods"][] = $property["setter"];
-								}
-							}
-							
-							if ($property["getter"]) {
-								if ($this->AddMethodToClass($property["getter"], $this->dump[$file_name]["classes"][$current])) {
-									$this->dump[$file_name]["classes"][$current]["methods"][] = $property["getter"];
-								}
-							}
-							
-							continue;
-					}
-					
-					// found method
-					if (eregi($this->regex_objc_method_params, $line, $captures)) {
-						$method = $this->ConvertObjcMethodToPascal($current, $line, $captures, $this->GetProtectedKeywords($this->current_class), true);						
-						if ($this->AddMethodToClass($method, $this->dump[$file_name]["classes"][$current])) {
-							$this->dump[$file_name]["classes"][$current]["methods"][] = $method;
-						}
-						
-					} elseif (eregi($this->regex_objc_method_no_params, $line, $captures)) {
-						$method = $this->ConvertObjcMethodToPascal($current, $line, $captures, $this->GetProtectedKeywords($this->current_class), false);
-						if ($this->AddMethodToClass($method, $this->dump[$file_name]["classes"][$current])) {
-							$this->dump[$file_name]["classes"][$current]["methods"][] = $method;
-						}
-					}
-					
-					// found the end
-					if (ereg("^@end", $line)) $got_class = false;
-				}
-				
-				// ==== got class ====
-				if ((eregi($this->regex_objc_class, $line, $captures)) || (eregi($this->regex_objc_class_no_super, $line, $captures))) {
-					$current = $captures[1];
-					$got_class = true;
-					
-					// check for instance variable section
-					if (eregi("{\s*$", $line)) $got_instance_vars = true;
-					
-					// get the protocol which the class conforms to
-					if (eregi($this->regex_objc_class, $line, $captures)) {
-						if ($captures[3]) $this->dump[$file_name]["classes"][$current]["conforms"] = $captures[3];
-					} else {
-						if ($captures[2]) $this->dump[$file_name]["classes"][$current]["conforms"] = $captures[2];
-					}
-					
-					// clean up the conforms string
-					if ($this->dump[$file_name]["classes"][$current]["conforms"]) {
-						$conform_protocols = explode(",", $this->dump[$file_name]["classes"][$current]["conforms"]);
-						
-						foreach ($conform_protocols as $protocol) {
-							$protocol = trim($protocol, "<> ");
-							$protocol_clean .= $protocol."$this->protocol_suffix, ";
-						}
-						
-						$protocol_clean = trim($protocol_clean, ", ");
-						$this->dump[$file_name]["classes"][$current]["conforms"] = $protocol_clean;
-						
-						$protocol_clean = "";
-					}
-					
-					$this->dump[$file_name]["classes"][$current]["name"] = $captures[1];
-					$this->dump[$file_name]["classes"][$current]["super"] = $captures[2];
-					$this->dump[$file_name]["classes"][$current]["super_class"] = &$this->dump["master"][$captures[2]];
-					$this->dump[$file_name]["classes"][$current]["file_name"] = $file_name;
-					$this->dump[$file_name]["classes"][$current]["file_clean"] = substr($file_name, 0, (strripos($file_name, ".")));
-					$this->dump[$file_name]["classes"][$current]["protected_keywords"] = array();
-					$this->dump[$file_name]["classes"][$current]["declared_methods"] = array();
-					$this->dump[$file_name]["category_methods"] = array();
-					
-					$this->current_class = &$this->dump[$file_name]["classes"][$current];
-					
-					// append master class listing
-					$this->dump["master"][$current] = &$this->dump[$file_name]["classes"][$current];
-					
-					// preparse for protected keywords
-					$this->PreparseClass($lines, $line_count);
-					
-					// preparse for category methods that may present naming conflicts
-					$category_methods = $this->PreparseCategoryMethods($file);
-					
-					// add category methods to protected keywords
-					if ($category_methods) $this->current_class["protected_keywords"] = array_merge($this->current_class["protected_keywords"], $category_methods);
-					
-					// print class hierarchy
-					if ($this->show_class_hierarchy) {
-						$this->GetClassHierarchy($this->current_class, $hierarchy);
-						$hierarchy_string = "";
-						foreach ($hierarchy as $value) {
-							$hierarchy_string .= "$value->";
-						}
-						$hierarchy_string = trim($hierarchy_string, "->");
-						print("	- $current: $hierarchy_string\n");
-					}
-					
-					$this->class_count ++;
-					//print_r($this->dump[$file_name]["classes"][$current]);
-				}
-				
-			}
-		
-		//print_r($this->dump[$file_name]["classes"][$current]);
-	}		
-	
-	// Parse categories which depend on another header
-	function ParseHeaderDependents ($file) {
-		$file_name = substr($file, (strripos($file, "/")) + 1, strlen($file));
-
-		$this->ParseHeaderCategories($file);
-			
-		print("+ Parsed $file_name for dependents\n");
-	}
-	
-	
-	// Main entry to parse a header
-	function ParseHeader ($file) {
-			$file_name = substr($file, (strripos($file, "/")) + 1, strlen($file));
-			$name_clean = substr($file_name, 0, (strripos($file_name, ".")));	
-			
-			// get framework we're parsing from
-			if (eregi("/([a-zA-Z]+)\.framework/", $file, $captures)) $this->framework = strtolower($captures[1]);
-			
-			// get the output path
-			$this->dump[$file_name]["path"] = "$this->root$this->out/$this->framework/$name_clean.inc";
-			$this->dump[$file_name]["path_partial"] = "$this->framework/$name_clean.inc";
-			$this->dump[$file_name]["framework"] = $this->framework;
-			$this->dump[$file_name]["name"] = $file_name;
-			$this->dump[$file_name]["name_clean"] = $name_clean;
-			$this->current_header = &$this->dump[$file_name];
-			
-			$this->ParseHeaderProtocols($file);
-			$this->ParseHeaderClasses($file);
-			$this->ParseHeaderTypes($file);
-			
-			print("+ Parsed $file_name\n");
-	}
-			
-	// Parse all AppKit and Foundation framework headers
-	function ParseCocoaFrameworks ($ignore_files, $parse_only) {
-		
-		foreach ($this->frameworks as $framework_name => $framework_info) {
-			
-			// framework is disabled
-			if ($framework_info["enabled"] != 1) continue;
-
-			if ($this->out != "/") {
-				$path = $this->root.$this->out."/".$framework_info["root"];
-			} else {
-				$path = $this->root.$framework_info["root"];
-			}
-				
-			$contents = ReadTextFile($path);
-			$lines = explode("\n", $contents);
-			
-			foreach ($lines as $line) {
-				if (eregi($framework_info["include_pattern"], $line, $captures)) {
-					$header = $captures[1].".h";
-					$path = $framework_info["headers"]."/$header";
-					
-					// main header
-					if ($parse_only) {
-						if (@in_array($header, $parse_only)) $this->ParseHeader($path);
-					} elseif (@!in_array($header, $ignore_files)) {
-						 $this->ParseHeader($path);
-					}
-
-					// header dependents
-					if ($parse_only) {
-						if (@in_array($header, $parse_only)) $this->ParseHeaderDependents($path);
-					} elseif (@!in_array($header, $ignore_files)) {
-						 $this->ParseHeaderDependents($path);
-					}
-				}
-			}
-			
-		}
-
-		// diagnostics
-		print("\n• Parsed $this->method_count methods in $this->class_count classes.\n\n");
-		
-		if ($this->warning_count > 0) print("• $this->warning_count warnings were encountered.\n\n");
-	}
-		
-	// Parse headers in a system framework
-	function ParseFramework ($ignore_files, $parse_only) {
-	}
-		
-	// Parses XML file generated by GEN_BRIDGE_METADATA -f /System/Library/Frameworks/AppKit.framework/
-	function ParseBridgeSupportXML ($file, $categories) {
-		$contents = ReadTextFile($file);
-			
-		$lines = explode("\n", $contents);
-		foreach ($lines as $line) {
-			
-			if ($got_informal_protocol) {
-				
-				if (eregi("<method type='(.*)' selector='(.*)'/>", $line, $captures)) {
-					
-					$set["name"] = $captures[2];
-					$set["name_pascal"] = str_replace(":", "_", $set["name"]);
-					$set["name_pascal"] = rtrim($set["name_pascal"], "_");
-					$set["types"] = $captures[1];
-					$set["param_string"] = $categories[$informal_protocol]["methods"][$captures[2]]["param_string"];
-					$set["method"] = &$categories[$informal_protocol]["methods"][$captures[2]];
-					
-					if ($captures[1][0] == "v") {
-						$set["kind"] = "procedure";
-					} else {
-						$set["kind"] = "function";
-					}
-					
-					// add the selector if the name isn't reserved for Pascal
-					if ((!in_array($set["name_pascal"], $this->reserved_keywords)) && (!in_array($set["name_pascal"], $this->reserved_methods))) {
-						$this->delegate_methods[$informal_protocol][] = $set;
-						$this->delegate_method_names[] = $set["name_pascal"];
-					}
-				}
-				
-				// end tag
-				if ($line == "</informal_protocol>") $got_informal_protocol = false;
-			}
-			
-			// got informal_protocol
-			if (eregi("<informal_protocol name='(.*)'>", $line, $captures)) {
-				$informal_protocol = $captures[1];
-				//print("\"$informal_protocol\", ");
-				$got_informal_protocol = true;
-			}
-		}
-		
-		print("+ Parsed bridge support XMl file at $file\n");
-		//print_r($this->delegate_methods);
-	}		
-		
-	// Parse all classes/categories (non-delegate) from the header
-	function ParseAllHeaderClasses ($file) {
-		$contents = ReadTextFile($file);
-			
-		$lines = explode("\n", $contents);
-		foreach ($lines as $line) {
-			
-			// remove external class macros
-			$line = eregi_replace("^[A-Z0-9]+_EXTERN_CLASS[[:space:]]+", "", $line);
-			
-			// classes
-			if (eregi($this->regex_objc_class, $line, $captures)) $this->cocoa_classes[] = $captures[1];
-			if (eregi($this->regex_objc_class_no_super, $line, $captures)) $this->cocoa_classes[] = $captures[1];
-			
-			// categories
-			if (eregi($this->regex_objc_category, $line, $captures)) {
-				$this->cocoa_categories[] = $captures[1];
-			}
-		}
-	}
-		
-	// Build array of all known Cocoa classes in frameworks	
-	function BuildCocoaClasses () {
-	
-		foreach ($this->frameworks as $framework_name => $framework_info) {
-			
-			// framework is disabled
-			if ($framework_info["enabled"] != 1) continue;
-			
-			$handle = opendir($framework_info["headers"]);
-			while (($file = readdir($handle)) !== false) {
-				if (eregi($framework_info["header_pattern"], $file)) {
-					$this->ParseAllHeaderClasses($framework_info["headers"]."/$file");
-				}
-			}
-			closedir($handle);
-		}
-	}		
-
-	function ProcessFile ($file, $print) {
-		$this->ParseHeader($file);
-		$this->ParseHeaderDependents($file);
-
-		if ($print) $this->PrintAllHeaders("", null, null, false);
-	}
-
-	function ParseDelegateClasses () {
-		
-		foreach ($this->frameworks as $framework_name => $framework_info) {
-			
-			// framework is disabled
-			if ($framework_info["enabled"] != 1) continue;
-			
-			$this->ParseBridgeSupportXML("$this->root".$framework_info["bridge"], $this->dump["categories"]);
-		}
-
-		// These are expressions which match valid class names or the names themself
-		$delegate_categories = array(	"(Delegation|Delegate|Notification|DataSource|Handler)+", 
-										"NSDraggingDestination", "NSDistantObjectRequestMethods", "NSDraggingSource",
-										"NSEditorRegistration", "NSFileManagerFileOperationAdditions", "NSPasteboardOwner",
-										);
-
-		$this->output = fopen("$this->root$this->out/foundation/$this->master_delegate_file.inc", "w+");
-		$this->PrintDelegateClass($delegate_categories);
-		fclose($this->output);
-		
-		$this->output = fopen("$this->root$this->out/$this->master_delegate_file.pas", "w+");
-		$this->PrintDelegateReference($delegate_categories);
-		fclose($this->output);
-	}
-	
-	function LoadTypeEncodings ($name) {
-		$contents = ReadTextFile("$this->root/$name");
-		
-		$lines = explode("\n", $contents);
-		foreach ($lines as $line) {
-			$row = explode("|", $line);
-			
-			$this->type_encodings[$row[0]][$row[1]] = $row[2];
-		}
-		
-		//print_r($this->type_encodings);
-	}
-	
-	// Prints out code to generate type encodings with GenerateTypeEncodings.p
-	// Paste the output of the function into GenerateTypeEncodings.p, run the program and save the output into a text file
-	// which is loaded into this script.
-	function PrintTypeEncodingGlue () {
-		$count = 0;
-		$block = true;
-		$block_count = 1;
-		$limit = 2000;
-		
-		foreach ($this->dump["all_methods"] as $class => $method) {
-			foreach ($method as $name) {
-				
-				if ($count == 0) {
-					print("\n");
-					print("procedure PrintGlue$block_count;\n");
-					print("begin\n");
-					
-					$block_count ++;
-				}
-				
-				$count ++;
-				
-				print("aMethod := class_getInstanceMethod(objc_getClass('$class'), sel_registerName(PChar('$name')));\n");
-				print("if aMethod <> nil then\n");
-				print("writeln('$class|$name|', method_getTypeEncoding(aMethod));\n");
-				
-				if ($count == $limit) {
-					print("end;\n");
-					$count = 0;
-				}
-			}
-		}
-		
-		if ($count < $limit) {
-			print("end;\n");
-			$block_count --;
-		}
-		
-		print("\n========= IMPLEMENTATION =========\n");
-		for ($i=1; $i < $block_count + 1; $i++) { 
-			print("PrintGlue$i;\n");
-		}
-	}
-		
-	function __construct ($directory, $out_directory, $frameworks, $show)  {
-		$this->root = $directory;
-		$this->out = $out_directory;
-		$this->show = $show;
-		if ($frameworks) {
-			foreach ($frameworks as $name) {
-				$this->frameworks[$name]["enabled"] = true;
-			}
-		}
-		$this->BuildCocoaClasses();
-		//$this->LoadTypeEncodings("TypeEncodingsAll.txt");
-	}
-}
-?>

+ 252 - 0
packages/cocoaint/utils/patches/cocoa-coredata-webkit.patch

@@ -0,0 +1,252 @@
+--- /Data/dev/cocoa/parsedheaders/newheaders3/appkit/NSWorkspace.inc	2010-09-22 20:20:31.000000000 +0200
++++ cocoa-skel/src/appkit/NSWorkspace.inc	2010-09-22 23:57:57.000000000 +0200
+@@ -26,7 +26,7 @@
+   NSWorkspaceLaunchNewInstance = $00080000;
+   NSWorkspaceLaunchAndHide = $00100000;
+   NSWorkspaceLaunchAndHideOthers = $00200000;
+-  NSWorkspaceLaunchAllowingClassicStartup = 0;
++  NSWorkspaceLaunchDefault = NSWorkspaceLaunchAsync or NSWorkspaceLaunchAllowingClassicStartup;
+ 
+ const
+   NSExcludeQuickDrawElementsIconCreationOption = 1 shl 1;
+--- /Data/dev/cocoa/parsedheaders/newheaders3/foundation/NSGeometry.inc	2010-09-22 20:21:06.000000000 +0200
++++ cocoa-skel/src/foundation/NSGeometry.inc	2010-09-22 23:57:57.000000000 +0200
+@@ -6,57 +6,51 @@
+ {$ifndef NSGEOMETRY_PAS_T}
+ {$define NSGEOMETRY_PAS_T}
+ 
++{$if defined(cpu64) or defined(cpuarm) or defined(win32)}
+ { Types }
+ type
+   NSPoint = CGPoint;
+   NSPointPtr = ^NSPoint;
+-  NSPointPointer = ^NSPoint;
+-  NSPointPointerPtr = ^NSPointPointer;
++  NSPointPointer = ^NSPointPtr;
+   NSPointArray = ^NSPoint;
+-  NSPointArrayPtr = ^NSPointArray;
+   NSSize = CGSize;
+   NSSizePtr = ^NSSize;
+-  NSSizePointer = ^NSSize;
+-  NSSizePointerPtr = ^NSSizePointer;
++  NSSizePointer = NSSizePtr;
+   NSSizeArray = ^NSSize;
+-  NSSizeArrayPtr = ^NSSizeArray;
+   NSRect = CGRect;
+   NSRectPtr = ^NSRect;
+-  NSRectPointer = ^NSRect;
+-  NSRectPointerPtr = ^NSRectPointer;
++  NSRectPointer = NSRectPtr;
+   NSRectArray = ^NSRect;
+-  NSRectArrayPtr = ^NSRectArray;
+-  NSRectEdge = NSUInteger;
+-  NSRectEdgePtr = ^NSRectEdge;
+-  NSPointPointer = ^NSPoint;
+-  NSPointPointerPtr = ^NSPointPointer;
+-  NSPointArray = ^NSPoint;
+-  NSPointArrayPtr = ^NSPointArray;
+-  NSSizePointer = ^NSSize;
+-  NSSizePointerPtr = ^NSSizePointer;
+-  NSSizeArray = ^NSSize;
+-  NSSizeArrayPtr = ^NSSizeArray;
+-  NSRectPointer = ^NSRect;
+-  NSRectPointerPtr = ^NSRectPointer;
+-  NSRectArray = ^NSRect;
+-  NSRectArrayPtr = ^NSRectArray;
+ 
+ { Defines }
+-const
+-  NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES = 1;
++{$define  NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES}
++
++{$endif cpu64 or cpuarm or win32}
+ 
+ { Types }
+ type
+-  
++{$ifdef NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES}
++  NSRectEdge = NSUInteger;
++{$else}
+   NSRectEdge = culong;
++{$endif}
++  NSRectEdgePtr = ^NSRectEdge;
+ 
+ { Constants }
++{$ifdef NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES}
++const
++  NSMinXEdge = CGRectMinXEdge;
++  NSMinYEdge = CGRectMinYEdge;
++  NSMaxXEdge = CGRectMaxXEdge;
++  NSMaxYEdge = CGRectMaxYEdge;
+ 
++{$else NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES}
+ const
+   NSMinXEdge = 0;
+   NSMinYEdge = 1;
+   NSMaxXEdge = 2;
+   NSMaxYEdge = 3;
++{$endif NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES}
+ 
+ {$endif}
+ {$endif}
+@@ -66,30 +60,37 @@
+ {$define NSGEOMETRY_PAS_R}
+ 
+ { Records }
++{$ifndef NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES}
+ type
+   _NSPoint = record
+     x: CGFloat;
+     y: CGFloat;
+   end;
+-NSPoint = _NSPoint;
+-_NSPointPtr = ^_NSPoint;
++  NSPoint = _NSPoint;
++  NSPointPtr = ^NSPoint;
++  NSPointPointer = NSPointPtr;
++  NSPointArray = ^NSPoint;
+ 
+ type
+   _NSSize = record
+     width: CGFloat;
+     height: CGFloat;
+   end;
+-NSSize = _NSSize;
+-_NSSizePtr = ^_NSSize;
++  NSSize = _NSSize;
++  NSSizePtr = ^NSSize;
++  NSSizePointer = NSSizePtr;
++  NSSizeArray = ^NSSize;
+ 
+ type
+   _NSRect = record
+     origin: NSPoint;
+     size: NSSize;
+   end;
+-NSRect = _NSRect;
+-_NSRectPtr = ^_NSRect;
+-
++  NSRect = _NSRect;
++  NSRectPtr = ^NSRect;
++  NSRectPointer = NSRectPtr;
++  NSRectArray = ^NSRect;
++{$endif not NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES}
+ 
+ {$endif}
+ {$endif}
+--- /Data/dev/cocoa/parsedheaders/newheaders3/foundation/NSObjCRuntime.inc	2010-09-22 20:21:06.000000000 +0200
++++ cocoa-skel/src/foundation/NSObjCRuntime.inc	2010-09-22 23:57:57.000000000 +0200
+@@ -8,7 +8,6 @@
+ 
+ { Defines }
+ const
+-  NS_BLOCKS_AVAILABLE = 1;
+   NS_BLOCKS_AVAILABLE = 0;
+   NSFoundationVersionNumber10_0 = 397.40;
+   NSFoundationVersionNumber10_1 = 425.00;
+@@ -62,16 +61,21 @@
+ 
+ { Types }
+ type
++{$if defined(cpu64) or defined(cpuarm) or defined(win32)}
+   NSInteger = clong;
+-  NSIntegerPtr = ^NSInteger;
+   NSUInteger = culong;
+-  NSUIntegerPtr = ^NSUInteger;
++{$else}
+   NSInteger = cint;
+-  NSIntegerPtr = ^NSInteger;
+   NSUInteger = cuint;
++{$endif}
++  NSIntegerPtr = ^NSInteger;
+   NSUIntegerPtr = ^NSUInteger;
+   NSComparisonResult = NSInteger;
+   NSComparisonResultPtr = ^NSComparisonResult;
++  NSEnumerationOptions = NSUInteger;
++  NSEnumerationOptionsPtr = ^NSEnumerationOptions;
++  NSSortOptions = NSUInteger;
++  NSSortOptionsPtr = ^NSSortOptions;
+ 
+ { Constants }
+ 
+@@ -81,6 +85,18 @@
+   NSOrderedDescending = 1;
+ 
+ const
++  NSEnumerationConcurrent = 1 shl 0;
++  NSEnumerationReverse = 1 shl 1;
++
++const
++  NSSortConcurrent = 1 shl 0;
++  NSSortStable = 1 shl 4;
++
++const
++  NSIntegerMax = high(NSInteger);
++  NSIntegerMin = low(NSInteger);
++  NSUIntegerMin = low(NSUinteger);
++  NSUIntegerMax = high(NSUinteger);
+   NSNotFound = NSIntegerMax;
+ 
+ {$endif}
+--- /Data/dev/cocoa/parsedheaders/newheaders3/foundation/NSPointerFunctions.inc	2010-09-22 20:21:06.000000000 +0200
++++ cocoa-skel/src/foundation/NSPointerFunctions.inc	2010-09-22 23:57:57.000000000 +0200
+@@ -25,7 +25,8 @@
+ { Types }
+ type
+   NSPointerFunctionsOptions = NSUInteger;
+-  NSPointerFunctionsOptionsPtr = ^NSPointerFunctionsOptions;
++  NSPointerFunctionsOptionsPointer = ^NSPointerFunctionsOptions;
++  NSPointerFunctionsOptionsPtr = NSPointerFunctionsOptionsPointer;
+ 
+ {$endif}
+ {$endif}
+@@ -53,8 +54,7 @@
+ 
+ {$ifdef FORWARD}
+   NSPointerFunctions = objcclass;
+-  NSPointerFunctionsPointer = ^NSPointerFunctions;
+-  NSPointerFunctionsPtr = NSPointerFunctionsPointer;
++  NSPointerFunctionsPtr = ^NSPointerFunctions;
+ 
+ {$endif}
+ 
+@@ -70,6 +70,7 @@
+ 
+     function initWithOptions(options: NSPointerFunctionsOptions): id; message 'initWithOptions:';
+     class function pointerFunctionsWithOptions(options: NSPointerFunctionsOptions): id; message 'pointerFunctionsWithOptions:';
++(*
+     procedure setItem (newValue: NSUInteger); message 'setItem:';
+     function item: NSUInteger; message 'item';
+     procedure setItem1 (newValue: Boolean); message 'setItem1:';
+@@ -80,6 +81,7 @@
+     function : NSUInteger; message '';
+     procedure setSrc (newValue: Pointer); message 'setSrc:';
+     function src: Pointer; message 'src';
++*)
+     procedure setUsesStrongWriteBarrier (newValue: Boolean); message 'setUsesStrongWriteBarrier:';
+     function usesStrongWriteBarrier: Boolean; message 'usesStrongWriteBarrier';
+     procedure setUsesWeakReadAndWriteBarriers (newValue: Boolean); message 'setUsesWeakReadAndWriteBarriers:';
+--- /Data/dev/cocoa/parsedheaders/newheaders3/foundation/NSRange.inc	2010-09-22 20:21:06.000000000 +0200
++++ cocoa-skel/src/foundation/NSRange.inc	2010-09-22 23:57:57.000000000 +0200
+@@ -6,11 +6,6 @@
+ {$ifndef NSRANGE_PAS_T}
+ {$define NSRANGE_PAS_T}
+ 
+-{ Types }
+-type
+-  NSRangePointer = ^NSRange;
+-  NSRangePointerPtr = ^NSRangePointer;
+-
+ {$endif}
+ {$endif}
+ 
+@@ -25,7 +20,8 @@
+     length: NSUInteger;
+   end;
+ NSRange = _NSRange;
+-_NSRangePtr = ^_NSRange;
++NSRangePtr = ^NSRange;
++NSRangePointer = NSRangePtr;
+ 
+ 
+ {$endif}

+ 52 - 0
packages/cocoaint/utils/patches/uikit.patch

@@ -0,0 +1,52 @@
+--- /Data/dev/cocoa/parsedheaders/iphoneheaders/foundation/NSObjCRuntime.inc	2010-10-04 00:21:29.000000000 +0200
++++ uikit-skel/src/foundation/NSObjCRuntime.inc	2010-10-03 22:12:15.000000000 +0200
+@@ -60,14 +60,17 @@
+ 
+ { Types }
+ type
++{$if defined(cpu64) or defined(win32)}
+   NSInteger = clong;
+   NSIntegerPtr = ^NSInteger;
+   NSUInteger = culong;
+   NSUIntegerPtr = ^NSUInteger;
++{$else}
+   NSInteger = cint;
+   NSIntegerPtr = ^NSInteger;
+   NSUInteger = cuint;
+   NSUIntegerPtr = ^NSUInteger;
++{$endif}
+   NSComparisonResult = NSInteger;
+   NSComparisonResultPtr = ^NSComparisonResult;
+ 
+@@ -79,6 +82,10 @@
+   NSOrderedDescending = 1;
+ 
+ const
++  NSIntegerMax = high(NSInteger);
++  NSIntegerMin = low(NSInteger);
++  NSUIntegerMin = low(NSUinteger);
++  NSUIntegerMax = high(NSUinteger);
+   NSNotFound = NSIntegerMax;
+ 
+ {$endif}
+--- /Data/dev/cocoa/parsedheaders/iphoneheaders/foundation/NSRange.inc	2010-10-04 00:21:29.000000000 +0200
++++ uikit-skel/src/foundation/NSRange.inc	2010-10-03 22:14:20.000000000 +0200
+@@ -10,9 +10,4 @@
+ 
+-{ Types }
+-type
+-  NSRangePointer = ^NSRange;
+-  NSRangePointerPtr = ^NSRangePointer;
+-
+ {$endif}
+ {$endif}
+ 
+@@ -26,6 +21,8 @@
+   end;
+ NSRange = _NSRange;
+ _NSRangePtr = ^_NSRange;
++NSRangePtr = ^NSRange;
++NSRangePointer = NSRangePtr;
+ 
+ 
+ {$endif}

+ 176 - 236
packages/cocoaint/utils/objp_parser.php → packages/cocoaint/utils/source/objp_parser.php

@@ -2,59 +2,22 @@
 
 class TObjPParser extends TPasCocoaParser {
 	
-	var $objc_id = "id";							// Default type for generic objects
-	var $objc_id_real = "id";						// The real type of generic objects (id)
-	var $sel_string = "SEL";						
 	var $trailing_underscore = true;
-	var $print_header_references = false;
 	
 	// ignore these classes when testing for ivar size
 	var $ignore_class_ivar_comparison = array(	"NSNibOutletConnector", "NSNibConnector", "NSNibControlConnector", "NSPredicateEditorRowTemplate", "NSSegmentedCell",
 												"NSSimpleHorizontalTypesetter", "NSInvocation", "NSPointerFunctions", "NSConstantString");
 	
-	var $reserved_keywords = array(	"const", "object", "string", "array", "var", "set", "interface", "classname", "unit",
-									"self", "type", "raise", "property", "to", "for", "with", "function", "procedure", "result",
-									"pointer", "create", "new", "dispose", "label", "packed", "record", "char", "class", "implementation",
-									
-									// identifiers from NSObject
-									"zone", 
-									);
-
-	var $replace_types = array(	"void"=>"Pointer", "BOOL"=>"Boolean", "long"=>"clong", "int"=>"cint",
-								"unsigned long"=>"culong", "unsigned short"=>"cushort", "void *"=>"Pointer", "unsigned int"=>"cuint",
-								"Class"=>"Pobjc_class", "uint"=>"cuint",
-								"uint8_t"=>"byte", "signed int"=>"cint", "const char"=>"char", "const void"=>"Pointer",
-								"const uint8_t"=>"byte", "unsigned"=>"cuint", "int32_t"=>"longint", "float"=>"single",
-								"unsigned long long"=>"culonglong", "int64_t"=>"clonglong", "uint32_t"=>"cardinal", "uint16_t"=>"word",
-								"unsigned char"=>"char", "short"=>"cshort", "double"=>"double", "long long"=>"clonglong",
-								
-								// ??? new in instance var parser: (add to main section eventually)
-								"signed char"=>"char", "uint64_t"=>"qword", 
-								
-								// work-arounds - the type replacement needs regex to handle with spaces I guess
-								"void*"=>"Pointer",
-								
-								// macros
-								"IBAction"=>"void", "IBOutlet"=>"",
-								
-								// special pointers
-								"const id *"=>"NSObjectArrayOfObjectsPtr", "Protocol *"=>"Protocol", "NSObject *"=>"NSObject",
-								"const char *"=>"PChar", "const void *"=>"Pointer", "unsigned char *"=>"Pointer", "char *"=>"PChar",
-								"unsigned *"=>"Pointer", "unichar *"=>"PWideChar", "const unichar *"=>"PWideChar", 
-								);
-		
 	// These methods require that the last parameter append a trailing underscore (if $trailing_underscore is on)
-	var $trailing_underscore_methods = array("- (void)copy:(id)sender;", "- (void)setNeedsDisplay:(BOOL)flag;");
-
-	// We use direct Cocoa classes now always
-	var $toll_free_bridge = array();
+	var $trailing_underscore_methods = array("- (void)copy:(id)sender;", "- (void)setNeedsDisplay:(BOOL)flag;","- (void*)QTMovie;","- (QTMovie *)QTMovie;","- (BOOL)load:(NSError **)error;");
 	
-	var $ignore_methods = array("observationInfo");	
+	var $ignore_methods = array("observationInfo"); 
 
 	// Converts an Objective-c method name to Pascal
 	function ConvertObjcMethodName ($method) {
 		$params = explode(":", $method);
 		$name = "";
+		$count = 0;
 		
 		if (count($params) > 1) {
 			foreach ($params as $value) {
@@ -72,18 +35,13 @@ class TObjPParser extends TPasCocoaParser {
 		$name = $this->ReplaceObjcType($name);
 		
 		return $name;
-	}	
-
-	// We use direct objc classes now so we don't need to replace them with references like in PasCocoa
-	function ReplaceNSTypesWithRef ($string) {
-		return $string;
-	}
+	} 
 
 	// Converts an Objective-C method to Pascal format 
-	function ConvertObjcMethodToPascal ($class, $source, $parts, $protected_keywords, $has_params) {
+	function ConvertObjcMethodToPascal ($class, $source, $parts, $protected_keywords, $has_params, $deprecatedmods) {
 		
-		// remove deprecated macros from method source
-		$source = eregi_replace("[[:space:]]*DEPRECATED_IN_MAC_OS_X_VERSION_[0-9]+_[0-9]+_AND_LATER", "", $source);
+		//print("$source\n");
+		//print_r($parts);
 		
 		// replace "hinted" params comment with hinted type
 		if ($this->replace_hinted_params) {
@@ -96,61 +54,64 @@ class TObjPParser extends TPasCocoaParser {
 			}
 
 			// return type
-			if (eregi("(/\*[[:space:]]*(.*)[[:space:]]*\*/)", $parts[2], $captures)) $parts[2] = $captures[2];
+			if (eregi("(/\*[[:space:]]*(.*)[[:space:]]*\*/)", $parts[2], $captures)) $parts[2] = $this->ReplaceRemoteMessagingModifiers($captures[2], $null);
 
 			//print_r($parts);
 
-		} else { // remmove comments from params and return type
+		} else { // remove comments from params and return type
 			$parts[4] = eregi_replace("(/\*.*\*/)", "", $parts[4]);
-			$parts[4] = trim($parts[4], " ");
+			$parts[4] = trim($parts[4]);
 
 			$parts[2] = eregi_replace("(/\*.*\*/)", "", $parts[2]);
-			$parts[2] = trim($parts[2], " ");
+			$parts[2] = $this->ReplaceRemoteMessagingModifiers($parts[2], $null);
 		}
-
+	
 		$return_type_clean = $parts[2];
+		$return_type_pointers = preg_replace("![^*]+!e", "", $return_type_clean);
+		$return_type_clean = trim($return_type_clean,"* 	");
 
 		// perform preformatting before attempting to protect keywords
 		$parts[2] = $this->FormatObjcType($parts[2], $modifiers);
-		$parts[4] = $this->FormatObjcParams($parts[4]);
-
-		// protect keywords in the parameter and return type
-		if (count($protected_keywords) > 0) {
-			foreach ($protected_keywords as $keyword) {
-				$parts[4] = istr_replace_word($keyword, $keyword."_", $parts[4]);
-				$parts[2] = istr_replace_word($keyword, $keyword."_", $parts[2]);
-			}
-		}
-
+		$parts[4] = $this->FormatObjcParams($parts[4], $variable_arguments);
+		//print($parts[4]."\n");
+		
 		if ($has_params) {
 			$name = $this->ConvertObjcMethodName($source);
 
 			// merge default protected keywords for the class/category
 			if ($this->default_protected["*"]) $protected_keywords = array_merge($this->default_protected["*"], $protected_keywords);
 			if ($this->default_protected[$class]) $protected_keywords = array_merge($this->default_protected[$class], $protected_keywords);
-
-			$param_array = $this->ConvertObjcParamsToPascal($parts[4], $protected_keywords, $variable_arguments);
+			
+			
+			$param_array = $this->ConvertObjcParamsToPascal($parts[4], $protected_keywords);
 			$params = "(".$param_array["string"].")";
 			$params_with_modifiers = "(".$param_array["string_with_modifiers"].")";
+			
 		} else {
 			$params = "";
 			$params_with_modifiers = "";
+			// no parameters -> definitely no underscore normally, but there are some
+			// conflicts...
 			$name = $parts[3];
+			// clean it up
+			if ($this->trailing_underscore) {
+				if (in_array($source, $this->trailing_underscore_methods)) $name = $name . "_";	
+			}
 			$param_array = null;
 			$variable_arguments = false;
 		}
 
 		// protect method name from keywords
 		if ($this->IsKeywordReserved($name)) $name .= "_";
-
+		
 		// replace objc type
-		$return_type = $this->ConvertReturnType($return_type_clean);
+		$return_type = $this->ConvertReturnType($return_type_clean,$return_type_pointers);
 
 		$virtual = "";
 		$class_prefix = "";
 
 		// determine the type based on return value
-		if (ereg($this->regex_procedure_type, $return_type_clean)) {
+		if (ereg($this->regex_procedure_type, $return_type_clean.$return_type_pointers)) {
 			$kind = "procedure";
 		} else {
 			$kind = "function";
@@ -181,15 +142,11 @@ class TObjPParser extends TPasCocoaParser {
 
 			$method = $class_prefix."function $name$params_with_modifiers: $return_type;$modifier$virtual";
 			$method_template = "[KIND] [PREFIX]$name"."[PARAMS]: [RETURN];$modifier";
-			$method_template_function = "function [PREFIX]$name"."[PARAMS]: [RETURN];$modifier";
 		}
 
 		$method_template_procedure = "procedure [PREFIX]$name"."[PARAMS];$modifier";
 		$method_template_function = "function [PREFIX]$name"."[PARAMS]: [RETURN];$modifier";
 
-		// ??? DEBUGGING
-		//print("$method\n");
-		
 		// build structure
 		$struct["def"] = $method;
 		$struct["template"] = $method_template;
@@ -197,6 +154,7 @@ class TObjPParser extends TPasCocoaParser {
 		$struct["template_procedure"] = $method_template_procedure;
 		$struct["objc_method"] = $this->CopyObjcMethodName($source);
 		$struct["class_prefix"] = $class_prefix;
+		if ($deprecatedmods != "") $struct["deprecated"] = $deprecatedmods.";";
 		//$struct["def_objc"] = eregi("(.*);", $source, $captures[1]);
 		if ($return_type == "void") $return_type = "";
 		$struct["return"] = $return_type;
@@ -217,7 +175,7 @@ class TObjPParser extends TPasCocoaParser {
 		// FPC bug work around
 		if (strlen($name) > $this->maximum_method_length) {
 			$struct["can_override"] = false;
-			print("	# WARNING: method $name can't override because the name is too long\n");
+			print(" # WARNING: method $name can't override because the name is too long\n");
 			$this->warning_count ++;
 		}
 
@@ -239,45 +197,104 @@ class TObjPParser extends TPasCocoaParser {
 			return true;
 		}
 	}
+
+  function PrintGlobalClassInfo($all_classes, $defined_classes, $anon_classes) {
+		// add all classes as anonymous external classes to a separate unit.
+		// They will be overridden by the actual definitions in the translated
+		// headers part of the main unit, but this way they can appear as record
+		// field types and as callback parameters
+
+		// open the output file if we not printing to terminal
+		if (!$this->show) {
+			$this->output = fopen("$this->root$this->out/AnonClassDefinitions".ucfirst($this->framework).".pas", "w+");
+		}
+		
+		$this->PrintOutput(0, "{ Parsed from ".ucfirst($this->framework)." }");
+
+		$date = @date("D M j G:i:s T Y");
+		
+		$this->PrintOutput(0, "");
+		// allows parameter names conflicting with field names
+		$this->PrintOutput(0, "{\$mode delphi}");
+		$this->PrintOutput(0, "{\$modeswitch objectivec1}");
+		// enables "external" after the semi-colon
+		$this->PrintOutput(0, "{\$modeswitch cvar}");
+		$this->PrintOutput(0, "");
+
+		$this->PrintOutPut(0,"unit AnonClassDefinitions".ucfirst($this->framework).";");
+		$this->PrintOutput(0, "");
+		$this->PrintOutput(0, "interface");
+		$this->PrintOutput(0, "");
+		$this->PrintOutput(0, "type");
+
+    foreach ($all_classes as $class)
+			$this->PrintOutput(1, $class." = objcclass; external;");
+
+		$this->PrintOutput(0, "");
+		$this->PrintOutput(0, "implementation");
+		$this->PrintOutput(0, "");
+		$this->PrintOutput(0, "end.");
+
+
+		// Now all anonymous external classes that have no real definition to an
+		// include file that is added to the main unit. This way it is possible
+		// to declare variables of these types in user programs without having to
+		// include the unit above will all anonymous classes (should not be used)
+
+		// open the output file if we not printing to terminal
+		if (!$this->show) {
+			$this->output = fopen("$this->root$this->out/$this->framework/AnonIncludeClassDefinitions".ucfirst($this->framework).".inc", "w+");
+		}
+		
+		$this->PrintOutput(0, "{ Parsed from ".ucfirst($this->framework)." }");
+
+		$date = @date("D M j G:i:s T Y");
+		
+
+		// add all classes as anonymous external classes. They will be overridden
+		// by the actual definitions in the translated headers, but this way they
+		// can appear as record field types and as callback parameters
+		$first = true;
+    foreach ($anon_classes as $class) {
+    	if (!in_array($class,$defined_classes)) {
+    		if ($first) {
+    			$this->PrintOutput(0, "type");
+    			$first = false;
+    		}
+				$this->PrintOutput(1, $class." = objcclass; external;");
+			}
+		}
+  }
+
 	
 	// Prints all classes from the header in Objective-P FPC format
 	function PrintHeader ($header) {
 		global $version;
+		//print_r($header);
+		//print_r($this->dump["categories"]);
 		
-		$this->output = fopen($header["path"], "w+");
+		// open the output file if we not printing to terminal
+		if (!$this->show) {
+			if ($this->merge_headers) {
+				$this->output = fopen($header["path_merge"], "w+");
+			} else {
+				$this->output = fopen($header["path"], "w+");
+			}
+		}
 
 		$this->PrintOutput(0, "{ Parsed from ".ucfirst($header["framework"]).".framework ".$header["name"]." }");
 
-		$date = date("D M j G:i:s T Y");
-		$this->PrintOutput(0, "{ Version $version - $date }");
+		$date = @date("D M j G:i:s T Y");
+		$this->PrintOutput(0, "{ Version: $version - $date }");
 		$this->PrintOutput(0, "");
 
 		$macro = strtoupper(substr($header["name"], 0, (strripos($header["name"], "."))));
 		
-		/*
-		if ($header["classes"]) {
-			$this->PrintOutput(0, "{\$ifdef HEADER}");
-			$this->PrintOutput(0, "{\$ifndef $macro"."_PAS_H}");
-			$this->PrintOutput(0, "{\$define $macro"."_PAS_H}");
-			$this->PrintOutput(0, "type");
-			
-			foreach ($header["classes"] as $class) {
-				
-				// Make a pointer to each class
-				$this->PrintOutput(1, $class["name"]."Pointer = Pointer;");
-			}
-		
-			$this->PrintOutput(0, "");
-			$this->PrintOutput(0, "{\$endif}");
-			$this->PrintOutput(0, "{\$endif}");
-		}
-		*/
-		
 		$this->PrintOutput(0, "");
 		$this->PrintOutput(0, "{\$ifdef TYPES}");
 		$this->PrintOutput(0, "{\$ifndef $macro"."_PAS_T}");
 		$this->PrintOutput(0, "{\$define $macro"."_PAS_T}");
-		$this->PrintTypes($header);
+		$this->PrintTypes($header, false);
 		$this->PrintOutput(0, "");
 		$this->PrintOutput(0, "{\$endif}");
 		$this->PrintOutput(0, "{\$endif}");
@@ -334,11 +351,14 @@ class TObjPParser extends TPasCocoaParser {
 			
 			if ($header["classes"]) {
 				foreach ($header["classes"] as $class) {
-					$this->PrintOutput(1, $class["name"]." = objcclass;");
-					$this->PrintOutput(1, $class["name"]."Pointer = ^".$class["name"].";");
+					if ($class["name"]) {
+						$this->PrintOutput(1, $class["name"]." = objcclass;");
+						$this->PrintOutput(1, $class["name"].$this->class_pointer_suffix." = ^".$class["name"].";");
+						// for consistency also offer Ptr-name variant
+						$this->PrintOutput(1, $class["name"]."Ptr = ".$class["name"].$this->class_pointer_suffix.";");
+					}
 				}
 			}
-			
 			$this->PrintOutput(0, "");
 			$this->PrintOutput(0, "{\$endif}");
 		}
@@ -350,8 +370,13 @@ class TObjPParser extends TPasCocoaParser {
 			$this->PrintOutput(0, "{\$define $macro"."_PAS_C}");
 
 			foreach ($header["classes"] as $class) {
-				//if (in_array($class["name"], $this->cocoa_classes))
-				$this->PrintClass($class);
+				if ($class["name"]) $this->PrintClass($class);
+			}
+
+			if (count($header["categories"]) > 0) {
+				foreach ($header["categories"] as $category) {
+					$this->PrintCategory($class, $category);
+				}
 			}
 
 			$this->PrintOutput(0, "");
@@ -369,12 +394,14 @@ class TObjPParser extends TPasCocoaParser {
 			foreach ($header["protocols"] as $protocol) {
 				$this->PrintOutput(1, "");
 				$this->PrintOutput(0, "{ ".$protocol["name"]." Protocol }");
+				if ($protocol["comment"]) $this->PrintOutput(0, $protocol["comment"]);
 				$this->PrintOutput(1, $protocol["name"]."$this->protocol_suffix = objcprotocol");
 
 				// print methods
 				if ($protocol["methods"]) {
 					foreach ($protocol["methods"] as $name => $method) {
-						$this->PrintOutput(2, $method["def"]." message '".$method["objc_method"]."';");
+						if ($method["comment"]) $this->PrintOutput(2, $method["comment"]);
+						$this->PrintOutput(2, $method["def"]." message '".$method["objc_method"]."';".$method["deprecated"]);
 					}
 				}
 				
@@ -386,15 +413,45 @@ class TObjPParser extends TPasCocoaParser {
 		}
 	}
 	
+	function PrintCategory ($class, $category) {
+
+		// declare real category if external
+		if ($category["external"]) {
+			$new_name = " name '".$category["external_name"]."'";
+		}
+		
+		$category_name = $category["name"].$this->category_suffix;
+		
+		$this->PrintOutput(0, "");
+		$this->PrintOutput(0, "{ $category_name }");
+		if ($category["comment"]) $this->PrintOutput(0, $category["comment"]);
+		
+		// print super class or protocol which the class conforms to
+		$this->PrintOutput(1, "$category_name = objccategory(".$category["super"].")");
+		
+		// print methods
+		if ($category["methods"]) {
+			foreach ($category["methods"] as $method) {
+				if ($method["comment"]) $this->PrintOutput(2, $method["comment"]);
+				$this->PrintOutput(2, $method["def"]." message '".$method["objc_method"]."';".$method["deprecated"]);
+			}
+		} 
+
+		$this->PrintOutput(1, "end; external$new_name;");
+	}
+		
 	function PrintClass ($class) {
 
 		$this->PrintOutput(0, "");
 		$this->PrintOutput(0, "{ ".$class["name"]." }");
+		
+		if ($class["comment"]) $this->PrintOutput(0, $class["comment"]);
 		//print_r($class["methods"]);
 		
+		
 		// print super class or protocol which the class conforms to
-		if ($class["conforms"]) {
-			$this->PrintOutput(1, $class["name"]." = objcclass(".$class["super"].", ".$class["conforms"].")");
+		if ($class["adopts"]) {
+			$this->PrintOutput(1, $class["name"]." = objcclass(".$class["super"].", ".$class["adopts"].")");
 		} elseif ($class["super"]) {
 			$this->PrintOutput(1, $class["name"]." = objcclass(".$class["super"].")");
 		}
@@ -416,145 +473,28 @@ class TObjPParser extends TPasCocoaParser {
 		if ($class["methods"]) {
 			$this->PrintOutput(0, "");
 			foreach ($class["methods"] as $method) {
-				$this->PrintOutput(2, $method["def"]." message '".$method["objc_method"]."';");
+				if ($method["comment"]) $this->PrintOutput(2, $method["comment"]);
+				$this->PrintOutput(2, $method["def"]." message '".$method["objc_method"]."';".$method["deprecated"]);
 			}
 		}
-
-		// print category-level methods
-		if (count($class["categories"]) > 0) {
-			foreach ($class["categories"] as $name => $category) {
-				$this->PrintOutput(0, "");
-				$this->PrintOutput(2, "{ Category: $name }");
-
-				if ($category["methods"]) {
-					foreach ($category["methods"] as $method) {
-						$this->PrintOutput(2, $method["def"]." message '".$method["objc_method"]."';");
-					}
-				}	
-			}
-		}
-
-		$this->PrintOutput(1, "end; external;");
-	}
-
-	function PrintDelegateReference ($valid_categories) {
-		global $version;
-
-		$date = date("D M j G:i:s T Y");
-		$this->PrintOutput(0, "{ Version $version - $date }");
-		$this->PrintOutput(0, "");
-
-		ksort($this->delegate_methods);
-		
-		$this->PrintOutput(0, "unit $this->master_delegate_file;");
-		$this->PrintOutput(0, "interface");
-		
-		$this->PrintOutput(0, "");
-		$this->PrintOutput(0, "{ Copy and paste these delegate methods into your real classes. }");
-		
 		
-		// implemented methods
-		foreach ($this->delegate_methods as $category => $selectors) {
-			if (in_array($category, $this->ignore_categories)) continue;
-			
-			// make sure the category is valid
-			$valid = false;
-			foreach ($valid_categories as $pattern) {
-				if (eregi($pattern, $category)) {
-					$valid = true;
-					break;
-				}
-			}
-			if (!$valid) continue;
-			
+		// print adopted protocol methods
+		if (count($class["protocols"]) > 0) {
 			$this->PrintOutput(0, "");
-			$this->PrintOutput(0, "type");
-			$this->PrintOutput(1, "$category = objccategory (NSObject)");
-			//$this->PrintOutput(1, "public");
-			
-			foreach ($selectors as $selector) {
-				
-				// FPC long name bug work-around
-				if (strlen($selector["name_pascal"]) > $this->maximum_method_length) continue;
-				
-				if ($selector["kind"] == "procedure") {
-					$this->PrintOutput(2, $selector["kind"]." ".$selector["name_pascal"].$selector["param_string"].";"." message '".$selector["name"]."';");
-				} else {
-					$this->PrintOutput(2, $selector["kind"]." ".$selector["name_pascal"].$selector["param_string"].": ".$selector["method"]["return"].";"." message '".$selector["name"]."';");
+			$this->PrintOutput(2, "{ Adopted Protocols }");
+			//print_r($this->dump["protocols"]);
+
+			foreach ($class["protocols"] as $name) {
+				if ($this->dump["protocols"][$name]) {
+					foreach ($this->dump["protocols"][$name] as $method) {
+						if (!$this->ClassContainsMethod($class, $method)) $this->PrintOutput(2, $method["def"]);
+					}
 				}
 			}
-			
-			$this->PrintOutput(1, "end;");
 		}
-		
-	}
-
-	function PrintIvarSizeComparison ($path) {
-		$count = 0;
-		$block = true;
-		$block_count = 1;
-		$limit = 2000;
-		
-		$handle = fopen($path, "w+");
-		if (!$handle) die("Bad path to size comparison output program!");
-		
-		fwrite($handle, "{\$mode objfpc}\n");
-		fwrite($handle, "{\$modeswitch objectivec1}\n");
 
-		fwrite($handle, "program IvarSize;\n");
-		fwrite($handle, "uses\n");
-		fwrite($handle, " objp,objcrtl,objcrtlmacosx;\n");
-		
-		// print derived classes
-		foreach ($this->cocoa_classes as $class) {
-			if (in_array($class, $this->ignore_class_ivar_comparison)) continue;
-			if ($previous == $class) continue;
-			
-			fwrite($handle, "type\n");
-			fwrite($handle, " TDerived$class = objcclass ($class)\n");
-			fwrite($handle, " extrabyte: byte;\n");
-			fwrite($handle, "end;\n");
-			
-			$previous = $class;
-		}
-		
-		// print procedures
-		foreach ($this->cocoa_classes as $class) {
-			if (in_array($class, $this->ignore_class_ivar_comparison)) continue;
-			if ($previous == $class) continue;
-			
-			if ($count == 0) {
-				fwrite($handle, "\n");
-				fwrite($handle, "procedure PrintGlue$block_count;\n");
-				fwrite($handle, "begin\n");
-				
-				$block_count ++;
-			}
-			
-			$count ++;
-			
-		 	fwrite($handle, " if class_getInstanceSize(TDerived$class) <> (class_getInstanceSize($class)+1) then\n");
-		    fwrite($handle, " writeln('size of $class is wrong: ',class_getInstanceSize(TDerived$class),' <> ',class_getInstanceSize($class)+1);\n");
-			
-			if ($count == $limit) {
-				fwrite($handle, "end;\n");
-				$count = 0;
-			}
-			
-			$previous = $class;
-		}
-		
-		if ($count < $limit) {
-			fwrite($handle, "end;\n");
-			$block_count --;
-		}
-		
-		fwrite($handle, "begin\n");
-		for ($i=1; $i < $block_count + 1; $i++) { 
-			fwrite($handle, " PrintGlue$i;\n");
-		}
-		fwrite($handle, "end.\n");
+		$this->PrintOutput(1, "end; external;");
 	}
 
 }
-?>
+?>

+ 3443 - 0
packages/cocoaint/utils/source/pascocoa_parser.php

@@ -0,0 +1,3443 @@
+<?php
+function ReadTextFile ($path) {
+	if ($handle = fopen($path, "r")) {
+		return fread($handle, 400 * 1024);
+		fclose($handle);
+	}
+}
+	
+function str_replace_word ($needle, $replacement, $haystack) {
+    $pattern = "/\b$needle\b/";
+    $haystack = preg_replace($pattern, $replacement, $haystack);
+    return $haystack;
+}
+
+function istr_replace_word ($needle, $replacement, $haystack) {
+    $pattern = "/\b$needle\b/i";
+    $haystack = preg_replace($pattern, $replacement, $haystack);
+    return $haystack;
+}
+
+function strtolowerref(&$str) {
+  $str = strtolower($str);
+}
+
+	// converts "STR_XX_YY_ZZ" to "Str Xx Yy Zz"
+	function DeprecatedMacroToDirective($str)
+	{
+		// AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_4 etc
+		if (preg_match("!DEPRECATED_(IN_.*VERSION_.*)_AND_LATER!", $str, $matches)) {
+			$str = strtolower($matches[1]);
+			// cleanup
+			$str = preg_replace("!in_mac_os_x_version_!", "in Mac OS X ", $str);
+			$str = preg_replace("!([0-9])_([0-9])!e", '\1.\2', $str);
+			return " deprecated '" . $str . " and later'";
+		// NS_DEPRECATED(__MAC_10_1,__MAC_10_6,__IPHONE_NA,__IPHONE_NA),
+		// __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_1,__MAC_10_6,__IPHONE_NA,__IPHONE_NA,
+		// NS_DEPRECATED_IPHONE(__IPHONE_2_0,__IPHONE_2_0),
+		// NS_DEPRECATED_MAC(__MAC_10_1, __MAC_10_5)
+		} elseif (preg_match("!DEPRECATED(_IPHONE|_MAC)?\(([^)]+)\)!", $str, $matches)) {
+			$str = strtolower($matches[2]);
+			$versions = preg_replace("!__MAC_!e", "Mac OS X ", $str);
+			$versions = preg_replace("!__IPHONE_!e", "iOS ", $versions);
+			$versions = preg_replace("!([0-9])_([0-9])!e", '\1.\2', $versions);
+			$deprecatedversions = explode(",", $matches[2]);
+			$result = "";
+			if ($matches[1] == "") {
+				$macindex = 2;
+				$iphoneindex = 4;
+			} elseif ($matches[1] == "_IPHONE") {
+				$macindex = -1;
+				$iphoneindex = 2;
+			} else {
+				$macindex = 2;
+				$iphoneindex = -1;
+			}
+			if (($macindex != -1) && !preg_match("!Mac OS X( Version)? NA|MAC_NA!", $deprecatedversions[$macindex])) {
+				$result = "in " . $deprecatedversions[$macindex] . " and later";
+			}
+			if (($iphoneindex != -1) && !preg_match("!iOS( Version)? NA|IPHONE_NA!", $deprecatedversions[$iphoneindex])) {
+				if ($result != "") $result .= ", ";
+				$result .= "in " . $deprecatedversions[$iphoneindex] . " and later";
+			}
+			return " deprecated '" . $result . "'";
+		}
+	}
+
+
+define("CAST_HANDLE", true);
+define("DONT_CAST_HANDLE", false);
+
+define("ACCESS_HANDLE_DIRECT", 1);
+define("ACCESS_HANDLE_FUNCTION", 2);
+
+define("REGISTER_SEL", true);
+define("DONT_REGISTER_SEL", false);
+
+define("USE_HANDLE", true);
+define("DONT_USE_HANDLE", false);
+	
+class TPasCocoaParser {
+
+	// Frameworks to parse (loaded from frameworks.xml)
+	var $frameworks = array();
+	
+	var $maximum_method_length = 111; 	// WE GET THIS ERROR: NSDelegatesAll.pas(6109,296) Error: Identifier not found "NSDelegateController_NSLayoutManagerDelegate_layoutManager_shouldUseTemporaryAttributes_forDrawingToScreen_atCharacterIndex_effectiveRange"
+	
+	var $output;									// current output file handle                        
+	var $root;										// root for printing/locating resources              
+	var $out;										// directory to print                                
+	var $show;										// print output to screen instead of file            
+	var $framework;									// current framework being parsed                    
+	var $current_class;								// reference to current class structure being parsed 
+	var $current_header;							// reference to current header structure being parsed
+	var $method_count;								// count of all methods parsed                       
+	var $class_count;								// count of all classes parsed                       
+	var $warning_count;								// count of parser warnings                          
+	var $parser_skipping;							// the parser is skipping lines in the current file  
+	var $inside_macro_block;						// the parser is inside a macro block, no nesting!
+	var $instance_var_scope;						// current scope of the instance variable parser
+	var $dump = array();							// Convert Pascal classes
+	var $delegate_methods = array();				// Delegate methods and types from GEN_BRIDGE_METADATA XML data
+	var $delegate_method_names = array();			// Delegate method name array
+	var $type_encodings = array();					// Master listing of type encodings for each method in the frameworks
+	
+	// Comments Builder
+	var $comment_eol;
+	var $comment_terminated;
+	var $comment_fragment;
+	var $comment_fragment_previous;
+	var $comment_fragment_open;
+	var $comment_previous;
+	var $comment_block_open;
+	var $comment_block_closed;
+	var $comment_header;
+	
+	// Macros Builder
+	var $macro_block = "";
+	var $in_macro_block = false;
+
+	/**
+	 * PARSER OPTIONS
+	 */
+	var $objc_id = "id";									// Default type for generic objects
+	var $sel_string = "SEL";								// The selector string type which registers selectors internally
+	var $protocol_suffix = "Protocol";						// All protocols append this suffix 
+	var $pointer_type_suffx = "Ref";						// NS*** pointers in parameter lists are suffixed with this
+	var $class_pointer_suffix = "Pointer";					// Pointers to NS*** classes are suffxed with this
+	var $register_selectors = true;							// Register selectors automatically inside the wrappers
+	var $show_added_messages = false;						// show messages when methods are added to a class
+	var $show_class_hierarchy = false;
+	var $objects_are_wrappers = false;						// Treat all objects (id) like wrappers. i.e aObject.Handle;
+	var $replace_hinted_params = false;						// replace comment hints with hinted type - (void * /* CMProfileRef */)colorSyncProfile;
+	var $trailing_underscore = false;						// Append the trailing underscore for last parameter
+	var $record_keyword = "record";							// The keyword used for printing records
+	var $bitpacked_record_keyword = "bitpacked record";		// The keyword used for printing bitpacked records
+	var $string_macro = "NSString";
+	var $category_suffix = "Category";								// To prevent naming conlicts all objccategories are suffixed with this work
+	var $parse_comments = false;							// Comments are parsed and inserted by context
+	var $merge_headers = false;								// Headers are printed by merging difference instead of overwritting
+	var $comment_break = "\n";								// This text will be inserted before each comment to break lines
+	var $comment_padding_left = " ";						// Padding applied to the left side of all comments
+	var $comment_padding_right = " ";						// Padding applied to the right side of all comments
+	var $varargs_param_name = "firstKey";					// The name of the first parameter for methods using varargs
+	
+	// array of all known framework classes (both regular and anonymous)
+	var $cocoa_classes = array("Protocol");
+	
+	// array of all anonymous external classes. This list will include
+	// classes that are first defined anonymously and then normally
+	var $anon_cocoa_classes = array();
+	
+	// array of all defined external classes. This list will only
+	// include classes that are completely defined
+	var $defined_cocoa_classes = array();
+
+	// array of function pointer types that are declared without an indirection
+	// (e.g. NSUncaughtExceptionHandler in NSException.h) -> do not add Ptr
+	// suffix when deriving the pointer type
+	var $implicit_function_pointer_types = array();
+	
+	// array of opaque struct pointer types
+	var $opaque_structs = array();
+	
+	// array of all known framework categories					                     
+	var $cocoa_categories = array(); 						                 
+
+	// Pascal keywords to protect
+	var $reserved_keywords = array( "const", "object", "string", "array", "var", "set", "interface", "unit", "begin", "end",
+									"type", "raise", "property", "to", "for", "with", "function", "procedure", "result",
+									"pointer", "create", "new", "dispose", "label", "packed", "record", "class", "implementation",
+									);
+
+									
+	// FPC methods that can't be overloaded
+	var $reserved_methods = array("");
+	
+	// Types which can not be altered by reserved keywords
+	var $reserved_types = array("Pointer");
+	
+	// Objective-c types to convert
+	var $replace_types = array("BOOL"=>"Boolean", "long"=>"clong", "int"=>"cint",
+								"unsigned long"=>"culong", "unsigned short"=>"cushort", "void *"=>"Pointer", "unsigned int"=>"cuint",
+								"Class"=>"Pobjc_class", "uint"=>"cuint",
+								"uint8_t"=>"cuint8", "signed int"=>"cint", "const char"=>"char", "const void *"=>"Pointer",
+								"const uint8_t"=>"cuint8", "unsigned"=>"cuint", "int32_t"=>"cint32", "float"=>"single",
+								"unsigned long long"=>"culonglong", "int64_t"=>"cint64", "uint32_t"=>"cuint32", "uint16_t"=>"cuint16",
+								"unsigned char"=>"char", "short"=>"cshort", "double"=>"double", "long long"=>"clonglong",
+								"uintptr_t"=>"culong","intptr_t"=>"clong",
+								"signed char"=>"char", "uint64_t"=>"cuint64", 
+								
+								// work-arounds - the type replacement needs regex to handle with spaces I guess
+								"void*"=>"Pointer",
+								
+								// macros
+								"IBAction"=>"void", "IBOutlet"=>"",
+								
+								// special pointers
+								"const id *"=>"NSObjectArrayOfObjectsPtr", "Protocol *"=>"objc_protocol", "NSObject *"=>"NSObject",
+								"const char *"=>"PChar", "const void *"=>"Pointer", "unsigned char *"=>"PByte", "char *"=>"PChar",
+								"unsigned *"=>"pcuint", "unichar *"=>"PChar", "const unichar *"=>"PChar", 
+								);
+		
+	// These "types" are hints to the Objective-C garbage collector
+	var $garbage_collector_hints = array("__strong", "__weak", "volatile", "___strong", "___weak");
+
+	// These identifiers are used with remote messaging
+	var $remote_messaging_modifiers = array("oneway", "in", "out", "inout", "bycopy", "byref");
+
+	var $null_macros = array("IBOutlet", "IBAction");
+	
+	// External NSString macros. Additional values are imported from frameworks.xml
+	var $external_string_macros = "APPKIT_EXTERN|FOUNDATION_EXPORT|EXTERN|extern";
+
+	// Types which have known pointers declared in the headers
+	var $pointer_types = array(	// MacOSAll types
+								// C/Cocoa types
+								"void"=>"Pointer","const void"=>"Pointer",
+								"Boolean"=>"pboolean",
+								"clong"=>"pclong","cint"=>"pcint",
+								"culong"=>"pculong","cushort"=>"pcushort","cuint"=>"pcuint",
+								"cuint8"=>"pbyte","char"=>"PChar",
+								"clonglong"=>"pclonglong","culonglong"=>"pculonglong",
+								"cint64"=>"pcint64",
+								"cuint32"=>"pcuint32","cuint16"=>"pcuint16",
+								"cshort"=>"pcshort",
+
+								"single"=>"psingle", "double"=>"pdouble",
+								);
+	
+	// Types to ignore
+	var $ignore_types = array("CGFloat");
+	
+	// Comments (or fragments starting with the pattern) to ignore (regex)
+	var $ignore_comments = array();
+	
+	// Categories to ignore
+	// NSURLLoading is deprecated in 10.4 and later, and causes problems
+	// when parsing the iPhoneOS foundation
+	var $ignore_categories = array("NSURLLoading");
+	
+	// Methods to ignore
+	var $ignore_methods = array(	"retain", "release", "retainCount", "copyWithZone", "mutableCopyWithZone",
+									"allocWithZone", "alloc", "copy", "mutableCopy", "self_", "autorelease", "awakeFromNib",
+									"observationInfo",
+								);	
+	
+	// Lines to ignore
+	var $ignore_lines = array();
+	
+	// default protected keywords by class/category
+	// these may be useful if super classes were not parsed before
+	var $default_protected = array(	"*"=>array("description", "classDescription", "zone"),
+	//								"NSDeprecated"=>array("accessoryView"),
+									"NSToolbarSupport"=>array("toolbar"),
+									"DOMNode"=>array("version"),
+									"WebView"=>array("frame"),
+									"DOMImplementation"=>array("version"),
+									"NSTableView"=>array("cell","toolTip","menu"),
+									"NSMovie"=>array("QTMovie"),
+									"UIAcceleration"=>array("timestamp","x","y","z"),
+									);
+	
+	var $skip_blocks = array(	//"^#if __LP64__.*"=>"^#(else|endif)+",
+								"^#if __BLOCKS__"=>"^#(else|endif)+",
+								"^#if NS_BLOCKS_AVAILABLE"=>"^#(else|endif)+",
+								"^#ifndef CGFLOAT_DEFINED"=>"^#(else|endif)+",
+								);
+								
+	var $macro_blocks = array(	"^#if \(__LP64__\)"=>"\$ifdef cpu64",
+								"^#if __LP64__.*"=>"\$ifdef cpu64",
+								"^#if !__LP64__.*"=>"\$ifndef cpu64",
+								"^#if defined \(__LP64__\)"=>"\$ifdef cpu64",
+								"^#if ![[:space:]]*\(__LP64__\)"=>"\$ifndef cpu64",
+								"^#ifdef __BIG_ENDIAN__"=>"\$ifdef fpc_big_endian",
+								// not really clean (assumes all arm devices are embedded)
+								"^#if __LP64__ \|\| TARGET_OS_EMBEDDED \|\| TARGET_OS_IPHONE \|\| TARGET_OS_WIN32 \|\| NS_BUILD_32_LIKE_64"=>"\$if defined(cpu64) or defined(cpuarm) or defined(win32)",
+								// replacement must be updated once we support AppleTV (presumably defines TARGET_OS_EMBEDDED but not TARGET_OS_IPHONE)
+								"^#if __LP64__ \|\| (TARGET_OS_EMBEDDED && !TARGET_OS_IPHONE) \|\| TARGET_OS_WIN32 \|\| NS_BUILD_32_LIKE_64"=>"\$if defined(cpu64) or defined(win32)"
+								//"^#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_[0-9]+_[0-9]+"=>"*",
+								);
+	
+	// These macros are used to suggest which version of a framework the symbol is available in	but removed to assist the parser			
+	var $version_macros = array(	"[[:space:]]*DEPRECATED_IN_.*_VERSION_[0-9]+_[0-9]+_AND_LATER[[:space:]]*",
+									"[[:space:]]*AVAILABLE_.*_VERSION_[0-9]+_[0-9]+_AND_LATER_BUT_DEPRECATED_IN_.*_VERSION_[0-9]+_[0-9]+[[:space:]]*",
+									"[[:space:]]*AVAILABLE_.*_VERSION_[0-9]+_[0-9]+_AND_LATER[[:space:]]*",
+									"[[:space:]]*AVAILABLE_.*_VERSION_[0-9]+_[0-9]+[[:space:]]*",
+									"[[:space:]]*.*_VERSION_MAX_ALLOWED[[:space:]]*",
+									"[[:space:]]__OSX_AVAILABLE.*\([^)]+\)",
+									);
+								
+																		
+	/**
+	 * COMMON REGULAR EXPRESIONS
+	 */
+	var $regex_objc_method_params = "^(-|\+)[[:space:]]*\(([^)]*)\)[[:space:]]*([a-zA-Z0-9]+):(.*);";
+	var $regex_objc_method_no_params = "^(-|\+)[[:space:]]*\(([^)]*)\)[[:space:]]*([a-zA-Z0-9]+);";
+	var $regex_objc_method_partial = "^(-|\+)[[:space:]]*\(([^)]*)\)[[:space:]]*([a-zA-Z0-9]+):(.*)";
+	var $regex_objc_method_terminate = "(.*);[[:space:]]*$";
+	var $regex_objc_category = "^@interface ([a-zA-Z]+)[[:space:]]*\(([a-zA-Z]+)\)";
+	var $regex_objc_class = "^@interface ([a-zA-Z]+)[[:space:]]*:[[:space:]]*([a-zA-Z]+)[[:space:]]*(<(.*)>)*";
+	var $regex_objc_class_no_super = "^@interface ([a-zA-Z]+)[[:space:]]*<(.*)>[[:space:]]*";
+	var $regex_objc_protocol = "^@protocol ([a-zA-Z]+)";
+	var $regex_procedure_type = "^[[:space:]]*(void|IBAction)+[[:space:]]*$";
+	var $regex_scope_compiler_directive = "^\s*@(private|protected|public)(;*)+\s*$";
+	var $regex_objc_property_attributes = "^@property[[:space:]]*\(([^)]*)\)[[:space:]]*([a-zA-Z_0-9]+)[[:space:]]*(\*)*[[:space:]]*(.*);";
+	var $regex_objc_property = "^@property[[:space:]]*([a-zA-Z_0-9]+)[[:space:]]*(\*)*[[:space:]]*(.*);";
+	var $regex_objc_anon_class = "^@class[[:space:]]*(.*);";
+	// $1 = return type
+	// $2 = pointer modifiers
+	// $3 = inline para name if any
+	// $4 = parameteres
+	var $pregex_function_pointer = "!^\s*([^*]+)\s*([*]*)\s*\(\s*[*]\s*(\w+)?\s*\)\s*\((.*)\)\s*;\s*$!";
+	// same as above except no ";" at the end
+	var $pregex_function_pointer_c_paratype = "!^\s*([^*]+)\s*([*]*)\s*\(\s*[*]\s*(\w+)?\s*\)\s*\((.*)\)\s*$!";
+	// Obj-C: additional brackets and para name
+	// $1 = return type
+	// $2 = pointer modifiers for return type
+	// $3 = inline type name if any
+	// $4 = parameters
+	// $5 = para name
+	// last "word" is next part of method name before next colon
+	var $pregex_function_pointer_objc_paratype = "!^\s*\(([^*]+)\s*([*]*)\s*\(\s*[*]\s*(\w+)?\s*\)\s*\((.*)\)\s*\)\s*(\w+)\s*\w+\s*$!";
+	// the (*) for the function pointer is "optional" in the sense that you can
+	// also declare a (useless?) function type (i.e., without the pointer) and
+	// then afterwards declare variables to be pointers to this type
+	var $pregex_function_pointer_typedef = "!^\s*typedef\s*([^*]+)\s*([*]*)\b\s*(?:\(\s*([*])\s*(\w+)?\s*\)|(\w+))\s*\((.*)\)\s*(\w+)?\s*;\s*$!";
+	
+	// semi-colon optional because sometimes on next line with availability
+	// macro
+	// $1 = return type
+	// $2 = pointer modifiers for return type
+	// $3 = function name
+	// $4 = parameters
+	var $pregex_external_function_end = "\s+([^*]+)\s*([*]*)\b\s*(\w+)\s*\((.*)\)\s*;?\s*$!";
+	
+	var $pregex_deprecated_macro = "!DEPRECATED!";
+
+	/**
+	 * UTILITIES
+	 */
+	
+// Skips blocks in the current file being parsed
+	function SkipBlock ($line) {
+		
+		if ($line != "") {
+			foreach ($this->skip_blocks as $key => $value) {
+				if (@ereg($key, $line)) {
+					$this->parser_skipping = true;
+				}
+				if (@ereg($value, $line)) {
+					$this->parser_skipping = false;
+				}
+			}
+		}
+		
+		return $this->parser_skipping;
+	}
+	
+	function IsKeywordReserved($keyword) {
+		$keyword = strtolower($keyword);
+		if (in_array($keyword, $this->reserved_keywords)) return true;
+		if (($this->current_class != null) &&
+		    ($this->dump["master"][$this->current_class["name"]] ["field_names"] != null) &&
+		    in_array($keyword, $this->dump["master"][$this->current_class["name"]] ["field_names"])) return true;
+	}
+	
+	// Replace type with pointer equivalent
+	function ReplacePointerType ($type) {
+		$found = false;
+		
+		// all classes are implicit pointer types
+		if (in_array($type, $this->cocoa_classes)) return $type;
+		
+		// function pointer types are sometimes also implicit
+		// pointers
+		if (in_array($type, $this->implicit_function_pointer_types)) return $type;
+
+		// PPointer = ^Pointer
+		if ($type == "Pointer") return "PPointer";
+		if ($type == "PChar") return "PPChar";
+		
+		// use preferred pointer type
+		foreach ($this->pointer_types as $objc_type => $replace_type) {
+			if ($objc_type == $type) {
+				$found = true;
+				$type = $replace_type;
+				break;
+			}
+		}
+		
+		//$type = "Pointer {".$type."}";
+		// use generic pointer type
+		if (!$found)
+			$type = $type."Ptr";
+		
+		return $type;
+	}
+	
+	// Makes a struct field into an inline array (or returns field un-changed)
+	function MakeFieldInlineArray ($io_field, $line, $name, $type) {
+
+		if (eregi("\[([0-9]+)\];", $line, $array_size)) {
+			$length = (int)$array_size[1] - 1;
+			if ($length > 0) {
+				$io_field = "    $name: array[0..$length] of $type;";
+			}
+		}
+		
+		return $io_field;
+	}
+
+	// Makes a type bitpacked (or returns type un-changed)
+	function MakeFieldBitPacked ($ioType, $field, &$bitpacked) {
+		$bitpacked = false;
+		
+		if (preg_match("!:([0-9]+)\s*(?:__attribute__\(\([^)]*\)\))?\s*;$!", $field, $bitpack)) {
+			$length = (int)$bitpack[1];
+			if ($length > 1) {
+				$ioType = "0..((1 shl $length)-1)";
+			} else {
+				$ioType = "0..$length";
+			}
+			
+			$bitpacked = true;
+		}
+		
+		return $ioType;
+	}
+
+	// Replace objc type with preferred type
+	function ReplaceObjcType ($type) {
+	
+		foreach ($this->replace_types as $objc_type => $replace_type) {
+			if ($objc_type == $type) {
+				$type = $replace_type;
+				break;
+			}
+		}
+		
+		return $type;
+	}
+		
+	// Replace garbage collector hints
+	function ReplaceGarbageCollectorHints ($string, &$io_hint) {
+		$io_hint = false;
+		
+		foreach ($this->garbage_collector_hints as $hint) {
+			$out_string = str_ireplace($hint, "", $string);
+			if ($out_string != $string) {
+				$io_hint = $hint;
+				$string = $out_string;
+			}
+		}
+		
+		return $string;
+	}
+	
+	// Replace remote message passing modifiers
+	function ReplaceRemoteMessagingModifiers ($string, &$io_modifier) {
+		$io_hint = false;
+
+		foreach ($this->remote_messaging_modifiers as $modifier) {
+			$out_string = preg_replace("!\b".$modifier."\b!", "", $string);
+			if ($out_string != $string) {
+				$io_modifier = $modifier;
+				$string = $out_string;
+			}
+		}
+			
+		return trim($string);
+	}
+	
+	
+	// Replace type of reference parameter with pointer
+	function ReplaceReferenceParameterType ($type) {
+		$type = $this->ReplaceObjcType($type);
+		return $this->ReplacePointerType($type);
+	}
+	
+	// Replace a framework class with generic id and comment hint
+	function ReplaceFrameworkClassWithID ($string) {
+		foreach ($this->cocoa_classes as $class) {
+			$string = istr_replace_word($class, $this->objc_id, $string);
+		}
+		return $string;
+	}
+				
+	// Copies the name from an Objective-C method definition
+	function CopyObjcMethodName ($method) {
+		
+		// cut out comments first
+		$method = eregi_replace("(/\*.*\*/)", "", $method);
+		$method = eregi_replace("//.*$", "", $method);
+		$method = trim($method, " 	");
+		
+		$params = explode(":", $method);
+		$name = "";
+		
+		if (count($params) > 1) {
+			foreach ($params as $value) {
+				$value = trim($value, " 	");
+				
+				if (eregi("([a-zA-Z0-9_]+)[[:space:]]*$", $value, $captures)) $name .= $captures[1].":";
+				
+				/*
+				// paremeter with no label (or first parameter)
+				if (eregi("\([a-zA-Z0-9_]+\)[[:space:]]*([a-zA-Z0-9]+)[[:space:]]*$", $value, $captures)) {
+					if ($name != "") {
+						$name .= ":";
+					} else {
+						$name .= $captures[1].":";
+					}
+					
+					continue;
+				}
+				
+				// parameter with label
+				if (eregi("\([a-zA-Z0-9_]+\)[[:space:]]*[a-zA-Z0-9_]+[[:space:]]+([a-zA-Z0-9]+)$", $value, $captures)) $name .= $captures[1].":";
+				*/
+			}
+		} else {
+			if (eregi("([a-zA-Z0-9_]+)[[:space:]]*(;)*$", $method, $captures)) $name = $captures[1];
+		}
+		
+		return $name;
+	}
+
+	// in case of a non-function pointer and non-pointer type,
+	// split a C field expression (e.g. "long afield" or
+	// "long int :32") into its type and field name. Necessary
+	// to recognise name that "long int :32" means "a field
+	// without a name whose type/alignment is "long int" and that is
+	// bitpacked
+	function ExtractCFieldSimpleTypeAndSingleName($param) {
+//		print("Converting field $param\n");
+	
+		// remove all "const" occurrences to simplify matching
+		$clean_param = str_replace_word("const", "", $param);
+
+		$got_type = false;
+		// assume not a pointer type
+		if (preg_match("!^\s*(unsigned|signed)\b!", $clean_param, $signedunsigned)) {
+			$got_type = true;
+			$clean_param = preg_replace("!^\s*(unsigned|signed)\b!", "", $clean_param);
+		}
+		if (preg_match("!^\s*(char|short|int|long\s+long\s+int|long\s+int|long\s+long|long)\b!", $clean_param, $inttype)) {
+			$got_type = true;
+			$clean_param = preg_replace("!^\s*(char|short|int|long\s+long\s+int|long\s+int|long\s+long|long)\b!", "", $clean_param);
+		}
+		if ($got_type) {
+			// remove bitfield and array, are encoded later
+			$result["name"] = trim(preg_replace("!(?::.*)?(?:\[[^]]*\])?!","",$clean_param));
+			$result["type"] = trim(preg_replace("!\s+!", " ", $signedunsigned[0] . " " . $inttype[0]));
+		} else {
+			// remove "struct"
+			$clean_param = str_replace_word("struct", "", $clean_param);
+			// has to be "type fieldname"
+			preg_match("!^\s*(\w+)\b\s*(\w+)(?:\[[0-9]*\])?\s*!", $clean_param, $matches);
+			$result["name"] = $matches[2]; // can be empty
+			$result["type"] = $matches[1];
+		}
+//		print("field conversion result: ".$result["name"].": ".$result["type"]."\n");
+		return $result;
+	}
+
+	// adds a function callback type with name $name, and returns
+	// the name of the callback type
+	function AddCallback($name, $function_pointer) {
+		if ($this->current_header) {
+			$type = $this->current_header["name_clean"].ucwords($name);
+	
+			if (!@in_array($function_pointer, $this->current_header["types"]["callbacks"])) {
+				$count = 0;
+				while (@array_key_exists($type, $this->current_header["types"]["callbacks"])) {
+					$count ++;
+					$type = "$type$count";
+				}
+				
+				// append the new type to the the current class
+				$this->current_header["types"]["callbacks"][$type] = $function_pointer;  
+			} else {
+				// Use the name of the existing callback of matching type
+				$type = array_search($function_pointer, $this->current_header["types"]["callbacks"]);
+			}
+			return $type;
+		}
+		return "invalid_callback_type_because_no_current_header";
+	}
+	
+	function ExtractCParaNameAndType($param) {
+//		print("Converting $param\n");
+	
+		// remove all "const" occurrences to simplify matching
+		$clean_param = str_replace_word("const", "", $param);
+		// remove all spaces between multiple pointer modifiers
+		$clean_param = trim(preg_replace("![*]\s+[*]!", "**", $clean_param));
+		// 1) varargs
+		if ($clean_param == "...") {
+			$result["name"] = "";
+			$result["pointermods"] = "";
+			$result["type"] = "...";
+		// 2) type is a function pointer (does not yet match arrays of function
+		//    pointers!)
+		} elseif (preg_match($this->pregex_function_pointer_c_paratype, $clean_param, $matches)) {
+			$result["name"] = $matches[3];
+			// not correct; simply assume no "pointer to function pointer" types are
+			// used
+			$result["pointermods"] = "";
+			$funcptrtype = $this->ParseFunctionDeclaration($matches[1], $matches[2], "", $matches[4], false, "");
+			$result["type"] = $this->AddCallback($matches[3], $funcptrtype);
+		// 3) any other pointer type (including arrays)
+		} elseif (preg_match("!^([^*]*)([*]+)\s*(\w+(?:\[[0-9]*\])?)?\s*$!", $clean_param, $matches)){
+			$result["name"] = $matches[3]; // can be empty
+			$result["pointermods"] = $matches[2];
+			$result["type"] = trim($matches[1]);
+		// 4) basic C type (including arrays)
+		} else {
+			// definitely not a pointer type
+			$result["pointermods"] = "";
+			$got_type = false;
+			if (preg_match("!^\s*(unsigned|signed)!", $clean_param, $signedunsigned)) {
+				$got_type = true;
+				$clean_param = preg_replace("!^\s*(unsigned|signed)!", "", $clean_param);
+			}
+			if (preg_match("!^\s*(char|short|int|long\s+long\s+int|long\s+int|long\s+long|long)!", $clean_param, $inttype)) {
+				$got_type = true;
+				$clean_param = preg_replace("!^\s*(char|short|int|long\s+long\s+int|long\s+int|long\s+long|long)!", "", $clean_param);
+			}
+			if ($got_type) {
+				$result["name"] = trim($clean_param);
+				$result["type"] = trim($signedunsigned[0] . " " . $inttype[0]);
+			} else {
+				// remove "struct"
+				$clean_param = str_replace_word("struct", "", $clean_param);
+				// has to be "type paraname", or just "type"
+				preg_match("!^\s*(\w+)\b\s*(\w+(?:\[[0-9]*\])?)?\s*!", $clean_param, $matches);
+				$result["name"] = $matches[2]; // can be empty
+				$result["type"] = $matches[1];
+			}
+		}
+//		print("param conversion result: ".$result["name"].": ".$result["pointermods"].$result["type"]."\n");
+		return $result;
+	}
+
+	// Returns the parameter modifier string for a callback parameter type
+	function GetCallbackParameterModifiers ($type, $name) {
+		$modifiers = "";
+		$type = trim($type, "*");
+		
+		// if the name starts with * it's a pointer
+		// don't process framework classes since they're always pointers
+		if (ereg("^[[:space:]]*\*", $name)) { 
+			if (!in_array($type, $this->cocoa_classes)) $modifiers = "var ";
+		} 
+		
+		// double ** are always var
+		if (ereg("^[[:space:]]*\*\*", $name)) { 
+			$modifiers = "var ";
+		} 
+
+		return $modifiers;
+	}
+	
+	// Converts a C parameter string to Pascal
+	function ConvertCParamsPascal ($string) {
+		
+//		print("params: $string\n");
+		if ((trim($string) == "void")  || (trim($string) == "")) return "";
+
+		$params = explode(",", $string);
+		$count = 0;
+		$param_string = "";
+		
+		foreach ($params as $param) {
+			
+			$name_type = $this->ExtractCParaNameAndType($param);
+			$type = $name_type["type"];
+			$name = $name_type["name"];
+			$pointertype = $name_type["pointermods"];
+			
+			// create name if none is specified
+			if ($name == "") {
+				$count ++;
+				$name = "param$count";
+			}
+
+			// remove const keywords
+			$type = str_replace_word("const", "", $type);
+			$type = $this->ReplaceObjcType($type);
+
+			// Remove array brackets (NSUInteger[])p
+			if (eregi("\[[0-9]*\]", $name)) {
+				$orgtype = $this->EncodePointerModifiers($type,$pointertype);
+				$pointertype .= "*";
+				$type = $this->EncodePointerModifiers($type,$pointertype)." {array of $orgtype}";
+				$name = eregi_replace("\[[0-9]*\]", "", $name);
+			} else {
+				$type = $this->EncodePointerModifiers($type,$pointertype);
+			}
+			$modifier = "";
+			
+			if ($this->IsKeywordReserved($name)) $name .= "_";
+			
+			// multiple parameters
+			if ($type == "...") {
+				$param_string .= "varargs: array of const";
+				break;
+			}
+			
+			$param_string .= "$modifier$name: $type; ";
+		}
+		
+		$param_string = trim($param_string, "; ");
+		//print("$param_string\n");
+		return $param_string;
+	}
+	
+	// Remove OS X versions macros from a line
+	// NOTE: These should be re-inlcuded in Pascal
+	function RemoveVersionMacros ($line, &$deprecatedmods) {
+		if (preg_match($this->pregex_deprecated_macro,$line)) {
+			$deprecatedmods = DeprecatedMacroToDirective($line);
+		} else {
+			$deprecatedmods = "";
+		}
+		foreach ($this->version_macros as $macro) {
+			$line = eregi_replace($macro, "", $line);
+		}
+		return $line;
+	}
+	
+	// Insert macro blocks to replace c-style blocks
+	function InsertMacroBlocks ($line, &$in_macro_block) {
+		
+		// only insert if we are in a block already.
+		// NOTE: this does not handle nesting!
+		if ($in_macro_block) {
+			
+			// macro else statment
+			if (eregi("#else", $line)) {
+				return "{\$else}";
+			}
+
+			// macro endif statment
+			if (eregi("#endif", $line)) {
+				$in_macro_block = false;
+				return "{\$endif}";
+			}
+		}
+		
+		foreach ($this->macro_blocks as $key => $value) {
+			
+			if (eregi($key, $line, $captures)) {
+				$in_macro_block = true;
+				
+				// replace the c-macro with a Pascal version
+				if ($value == "*") {
+					$captures[0] = trim($captures[0], "#");
+					return "{\$".$captures[0]."}";
+				} else {
+					return "{".$value."}";
+				}
+			}
+		}
+	}
+
+
+	// Appends the current macro to a recipient and resets it's reference
+	function AppendCurrentMacro (&$recipient) {
+		if ($this->in_macro_block) {
+			$this->in_macro_block = false;
+			
+			$recipient[] = $this->macro_block;
+			//if (is_array($recipient)) $recipient[] = $this->macro_block;
+			//if (is_string($recipient)) $recipient .= $this->macro_block;
+		}
+	}
+	
+	// Returns the current macro and resets it's reference
+	function InsertCurrentMacro () {
+		if ($this->in_macro_block) {
+			$this->in_macro_block = false;
+			return $this->macro_block;
+		} else {
+			return null;
+		}
+	}
+
+	// Build the current macro block
+	function BuildMacroBlocks ($line) {
+		
+		// only insert if we are in a block already.
+		// NOTE: this does not handle nesting!
+		if ($this->in_macro_block) {
+			
+			// macro else statment
+			if (eregi("#else", $line)) {
+				$this->macro_block = "{\$else}";
+			}
+
+			// macro endif statment
+			if (eregi("#endif", $line)) {
+				$this->in_macro_block = false;
+				$this->macro_block = "{\$endif}";
+			}
+		}
+		
+		foreach ($this->macro_blocks as $key => $value) {
+			
+			if (eregi($key, $line, $captures)) {
+				$this->in_macro_block = true;
+				
+				// replace the c-macro with a Pascal version
+				if ($value == "*") {
+					$captures[0] = trim($captures[0], "#");
+					$this->macro_block = "{\$".$captures[0]."}";
+				} else {
+					$this->macro_block = "{".$value."}";
+				}
+			}
+		}
+	}
+	
+	// Trim a comment string
+	function TrimComment ($comment, $preserve_line_endings) {
+		
+		// trim line breaks
+		if (!$preserve_line_endings) $comment = trim($comment, "\n");
+		
+		// remove remains of C comments
+		$comment = eregi_replace("^[!*/ 	]+", "", $comment);
+		$comment = eregi_replace("[!*/ 	]+$", "", $comment);
+		
+		// remove all Pascal comment characters to prevent nesting
+		$comment = str_replace(array("{", "}"), "", $comment);
+		
+		//print("$comment\n");	
+		return $comment;
+
+	}
+	
+	// Builds comments from $line spaning multiple lines or at the end of lines
+	// Returns a terminated comment string or a fragment in $fragment for futher processing
+	function BuildComment ($line, $file) {
+		
+		// set the current comment header being parsed
+		$this->comment_header = $file;
+		
+		// comment parsing is off, bail!
+		if (!$this->parse_comments) return;
+		
+		// single-line comments
+		// ??? check if this is at the end of line or not! this could be a full line comment
+		if (eregi("[[:space:]]+//(.*)", $line, $captures)) {
+			//print("$captures[1]\n");
+			
+			// ignore comment
+			foreach ($this->ignore_comments as $pattern) {
+				if (eregi($pattern, $captures[1])) return;
+			}
+			
+			$this->comment_eol = $captures[1];
+			return;
+		}
+		
+		// multi-line comments terminated
+		if (eregi("/\*(.*)\*/", $line, $captures)) {
+			//print("$captures[1]\n");
+			
+			// ignore comment
+			foreach ($this->ignore_comments as $pattern) {
+				if (eregi($pattern, $captures[1])) return;
+			}
+			
+			$this->comment_terminated = $this->TrimComment($captures[1], false);
+			return;
+		}
+		
+		// terminate comment fragment 
+		if ($this->comment_fragment_open) {
+			if (eregi("(.*)\*/", $line, $captures)) {
+				
+				// append fragment
+				$comment = $this->TrimComment($captures[1], false);
+				if ($comment) $this->comment_fragment .= $comment;
+				
+				// closed comment block
+				if (!$captures[1]) {
+					$this->comment_block_closed = true;
+				}
+				
+				// set terminated comment with fragment
+				$this->comment_terminated = $this->comment_fragment;
+				
+				// add extra line break for comment blocks
+				if (($this->comment_block_open) && ($this->comment_block_closed)) {
+					// ??? the printing will cut this out if we add line endings!
+					$this->comment_terminated = "$this->comment_fragment";
+				}
+				
+				$this->comment_fragment = null;
+				$this->comment_fragment_open = false;
+				
+				$this->comment_block_open = false;
+				$this->comment_block_closed = false;
+				
+				return;
+			} else {
+				// build the fragment
+				$comment = $this->TrimComment($line, true);
+
+				// ignore comment and stop building fragment
+				foreach ($this->ignore_comments as $pattern) {
+					if (eregi($pattern, $comment)) {
+						$this->comment_fragment = null;
+						$this->comment_fragment_open = false;
+
+						$this->comment_block_open = false;
+						$this->comment_block_closed = false;
+						
+						return;
+					}
+				}
+				
+				if (($this->comment_fragment_previous != $line) && ($comment)) $this->comment_fragment .= $comment."\n";
+				
+				$this->comment_fragment_previous = $line;
+				return;
+			}
+		}
+		
+		// start comment fragment
+		if (eregi("/\*(.*)", $line, $captures)) {
+			
+			$this->comment_terminated = null;
+
+			// ignore comment
+			foreach ($this->ignore_comments as $pattern) {
+				if (eregi($pattern, $captures[1])) return;
+			}
+			
+			$this->comment_fragment_open = true;
+			$this->comment_fragment = "";
+			$this->comment_block_open = true;
+			$this->comment_block_closed = false;
+			
+			// prevent against empty comments
+			if ((!$captures[1]) || ($captures[1] == "\n")) {
+				$this->comment_block_open = true;
+				return;
+			}
+			
+			// append the line if valid
+			$comment = $this->TrimComment($captures[1], false);
+			
+			if ($comment) $this->comment_fragment .= $comment;
+			
+			return;
+		}
+	}
+	
+	// Resets current comment references
+	function ResetComment () {
+		$this->comment_fragment = null;
+		$this->comment_eol = null;
+		$this->comment_terminated = null;
+		$this->comment_block_open = false;
+		$this->comment_block_closed = false;
+	}
+	
+	// Checks/sets if a comment is a duplicate in the file
+	function CheckDuplicateComment ($comment) {
+		if ((@!in_array($comment, $this->dump[$this->comment_header]["comments"])) && ($comment)) {
+			$this->dump[$this->comment_header]["comments"][] = $comment;
+			return true;
+		} else {
+			return false;
+		}
+		
+	}
+	
+	// Appends the eol comment to the output and clears the reference
+	function AppendEOLComment () {
+		if ($this->comment_eol) {
+			$comment = "  // ".$this->TrimComment($this->comment_eol, false);
+			$this->comment_eol = "";
+			return $comment;
+		} else {
+			return null;
+		}
+	}
+	
+	// Inserts the recently terminated comment to the output on a new line and clears the reference
+	function InsertCurrentComment () {
+		if (($this->comment_terminated) && ($this->CheckDuplicateComment($this->comment_terminated))) {
+			
+			if ($this->comment_terminated != $this->comment_previous) $comment = "$this->comment_break{".$this->comment_padding_left.$this->TrimComment($this->comment_terminated, false).$this->comment_padding_right."}";
+			
+			$this->comment_previous = $this->comment_terminated;
+			$this->comment_terminated = "";
+			
+			return $comment;
+		} else {
+			return null;
+		}
+	}
+	
+	// Appends the recently terminated comment to a recipient and clears the reference
+	function AppendCurrentComment (&$recipient) {
+		if (($this->comment_terminated) && ($this->CheckDuplicateComment($this->comment_terminated)) && (gettype($recipient) == "array")) {
+			
+			if ($this->comment_terminated != $this->comment_previous) $comment = "$this->comment_break{".$this->comment_padding_left.$this->TrimComment($this->comment_terminated, false).$this->comment_padding_right."}";
+			
+			$recipient[] = $comment;
+			//if (is_array($recipient)) $recipient[] = $comment;
+			//if (is_string($recipient)) $recipient .= $comment;
+			
+			$this->comment_previous = $this->comment_terminated;
+			$this->comment_terminated = "";
+		}
+	}
+	
+	// Removes all comments from a line
+	function RemoveComments ($line) {
+		// remove single-line comments
+		$line = eregi_replace("[[:space:]]+//(.*)", "", $line);
+		
+		// remove multi-line comments /* ... */
+		$line = eregi_replace("/\*.*\*/", "", $line);
+		
+		return $line;
+	}
+	
+	// Performs additional formatting on Objective-c type i.e. (out NSObject **)
+	function FormatObjcType ($type, &$modifiers) {
+		$modifiers = "";
+		
+		// toss out all const identifiers
+		$type = istr_replace_word("const", "", $type);
+		
+		// replace inout paramaters
+		$type = istr_replace_word("inout", "", $type);
+		$type = istr_replace_word("out", "", $type);
+		$type_clean = trim($type, "* ");
+		
+		// Replace types before cleaning
+		$type = $this->ReplaceObjcType($type);
+		
+		// Remove protocol which type conforms to (id <NSURLHandleClient>)
+		$type = eregi_replace("<.*>", "", $type);
+		
+		// Remove array brackets (NSUInteger[])p
+		$type = eregi_replace("\[[0-9]*\]", "", $type);
+		
+		// var params to non-object types (NSRange *)
+		if (ereg("([a-zA-Z0-9_]+)[[:space:]]*[*]+$", $type, $captures)) { 
+			if (!in_array($captures[1], $this->cocoa_classes)) {
+				$type = $this->ReplaceReferenceParameterType($type_clean);
+				//$modifiers = "var ";
+			}
+		} 
+		
+		// Handle NS*** pointers (NSError **)
+		if (ereg("(NS[a-zA-Z0-9_]+)[[:space:]]*\*\*$", $type, $captures)) { 
+			if (in_array($captures[1], $this->cocoa_classes)) {
+				$type = "$type_clean$this->class_pointer_suffix";
+			}
+		}
+		
+		// clean the type
+		$type = trim($type, "* 	");
+		
+		//print("$type\n");
+		return $type;
+	}
+	
+	// Performs additional formatting on Objective-c parameter types		
+	function FormatObjcParams ($string, &$variable_arguments) {
+		$params = explode(":", $string);
+		$string = "";
+		$variable_arguments = false;
+		// print_r($params);
+		
+		if (count($params) > 0) {
+			foreach ($params as $value) {
+				
+				// parameter is varargs
+				if (eregi("(.*),[[:space:]]*\.\.\.", $value)) {
+					$string .= ":(id)$this->varargs_param_name";
+					$variable_arguments = true;
+					//print("$value\n");
+					continue;
+				}
+				
+				if (preg_match("!^[^(]*$!",$value)) {
+					// parameter without type -> id
+					$value = "(id)".$value;
+				}
+
+				// normal parameter
+				if (ereg("\((.*)\)", $value, $captures)) {
+					$new_value = $this->ReplaceObjcType($captures[1]);
+					
+					if ($new_value != $captures[1]) $value = ereg_replace("\((.*)\)", "($new_value)", $value);
+					
+					$string .= ":$value";
+					continue;
+				}
+				
+			}
+		}
+		$string = ltrim($string, ":");
+		return $string;
+	}
+	
+	// Converts an Objective-c parameter string to Pascal		
+	function ConvertObjcParamsToPascal ($string, $protected_keywords) {
+		$params = explode(":", $string);
+		$list = array();
+		$list["pairs"] = array();
+		$param_list = array();
+		//print_r($params);
+		//print("$string\n");
+		
+		if (count($params) > 0) {
+			
+			foreach ($params as $value) {
+				$value = trim($value);
+				$valid = false;
+				$modifiers = "";
+				
+				$value = $this->ReplaceRemoteMessagingModifiers($value, $null);
+				
+				// function pointer (callback)
+				if (preg_match($this->pregex_function_pointer_objc_paratype, $value, $captures)) {
+					$name = $captures[5];
+					
+					$function_pointer = $this->ParseFunctionDeclaration($captures[1], $captures[2], "", $captures[4], false, "");
+					$type = $this->AddCallback($name, $function_pointer);
+					$valid = true;
+				} elseif ((eregi("\(([a-zA-Z_]+).*\)([a-zA-Z_]+).*\.\.\.", $value, $captures)) || (eregi("(.*),[[:space:]]*\.\.\.", $value, $captures))) { // variable arguments
+					$name = $captures[2];
+					$type = $captures[1];
+					$valid = true;
+				} elseif (eregi("\((.*)\)[[:space:]]*([a-zA-Z_]+)", $value, $captures)) { // standard parameter
+					
+					$captures[1] = trim($captures[1]);
+					$type = $this->FormatObjcType($captures[1], $modifiers);
+					$name = $captures[2];
+					
+					$valid = true;
+				}
+				
+				if ($valid) {
+					
+					// protect reserved keywords
+					if ($this->IsKeywordReserved($name)) $name .= "_";
+					
+					if (!in_array($type, $this->reserved_types)) {
+						if ($this->IsKeywordReserved($type)) $type .= "_";
+					}
+
+					// can't have "boolean: boolean;" parameters
+					if (preg_match("!\b$name\b!i",$type)) $name .= "_";
+
+//					print("para name: \"$name\"\n");
+//					print_r("protected: \"$protected_keywords\"\n");
+					while (@in_array(strtolower($name), $protected_keywords)) $name .= "_";
+					
+					// case-insensitive in_array:
+//					if( preg_match("/\b$name\b/i", join(" ", array_values($protected_keywords))) ) $name .= "_";
+//					if (@in_array($type, $protected_keywords)) $type .= "_";
+					
+					// replace objc types
+					$type = $this->ReplaceObjcType($type);
+					
+					// make sure we label duplicate params, which are allowed in Objective-C
+					while (in_array($name, $param_list)) {
+						$count ++;
+						$name = "$name$count";
+					}
+					
+					// id is always a wrapper
+					if (($this->objects_are_wrappers) && ($type == $this->objc_id)) {
+						$name_list = "$type(GetHandle($name))";
+					} else {
+						$name_list = $name;
+					}
+					
+					// add modifiers to the name if there are any
+					$name_with_modifiers = $modifiers.$name;
+
+					// create pair array
+					$pair["name"] = $name;
+					$pair["type"] = $type;
+					
+					// append list
+					$list["pairs"][] = $pair;
+					$list["string_with_modifiers"] .= "$name_with_modifiers: $type; ";
+					$list["string"] .= "$name: $type; ";
+					$list["list"] .= "$name_list, ";
+					$param_list[] = $name;
+				}
+			}
+		}
+		// clean up the strings
+		$list["string"] = trim($list["string"], "; ");
+		$list["string_with_modifiers"] = trim($list["string_with_modifiers"], "; ");
+		$list["list"] = trim($list["list"], ", ");
+		
+		return $list;
+	}
+	
+	// Print string to output file
+	function PrintOutput ($indent, $string) {
+		for ($i=0; $i < $indent; $i++) { 
+			$indent_string .= "  ";
+		}
+		
+		if (($this->output) && (!$this->show)) fwrite($this->output, "$indent_string$string\n");
+		
+		if ($this->show) print("$indent_string$string\n");
+	}
+		
+	// Returns a class hierarchy array 
+	function GetClassHierarchy ($class, &$hierarchy) {
+		if (!$hierarchy) $hierarchy = array();
+		$hierarchy[] = $class["name"];
+		
+		if ($class["super_class"]) {
+			$hierarchy[] = $this->GetClassHierarchy($class["super_class"], $hierarchy);
+		} else {
+			$hierarchy[] = "NSObject";
+		}
+		
+		return $class["name"];
+	}
+	
+	// Returns all protected keywords in a class hierarchy
+	function GetProtectedKeywords ($in_class) {
+		$this->GetClassHierarchy($in_class, $hierarchy);
+		$keywords = array();
+		
+		foreach ($hierarchy as $class) {
+			if ($this->dump["master"][$class]["protected_keywords"]) {
+				foreach ($this->dump["master"][$class]["protected_keywords"] as $keyword) $keywords[] = strtolower($keyword);
+			}
+		}
+		
+		return $keywords;
+	}
+	
+	
+	// Returns header a category should be moved to
+	function FindCategoryHeader ($category) {
+		
+		foreach ($this->dump as $name => $header) {
+			if ((@array_key_exists($category, $header["classes"])) && ($category != "NSObject")) {
+				return $name;
+			}
+		}
+	}
+	
+	// Checks if $class (array) contains $method (array)
+	function ClassContainsMethod ($class, $method) {
+		if ($class["methods"]) {
+			foreach ($class["methods"] as $key) {
+				if ($key["name"] == $method["name"]) return true;
+			}
+		}
+	}
+	
+	// Adds a method structure to a class and performs checks for overloaded methods
+	function AddMethodToClass (&$method, &$class) {
+		
+		// ignore methods
+//		if (in_array($method["name"], $this->ignore_methods)) return false;
+		
+		// add comment to the method
+		$method["comment"] = $this->InsertCurrentComment();
+		
+		if (@!in_array($method["name"], $class["declared_methods"])) {
+			
+			$class["all"][$method["name"]] = $method;
+			$class["protected_keywords"][] = $method["name"];
+			$class["declared_methods"][] = $method["name"];
+			$this->dump["all_methods"][$class["name"]][] = $method["objc_method"];
+			
+			if ($this->show_added_messages) print("	@ Added ".$method["name"]." to ".$class["name"]."\n");
+
+			$this->method_count ++;
+			return true;
+		} else {
+			print("	! ".$method["def"]." already exists in ".$class["name"]." defined as ".$class["all"][$method["name"]]["def"]."\n");
+		}
+	}
+	
+	// Adds a typedef to the header and handles organization to prevent order conflicts
+	function AddTypeDef (&$header, $typedef) {
+		
+		//$this->AppendCurrentMacro($header["types"]["typedef"]);
+		$this->AppendCurrentComment($header["types"]["typedef"]);
+		if ($this->comment_terminated) $header["types"]["typedef"][] = $this->InsertCurrentComment();
+		
+		$header["types"]["typedef"][] = $typedef;
+	}
+		
+	// Returns a paramater list string with options to modify
+	function MakeParamList ($param_array, $use_handle, $cast_handle, $direct, $register_selector) {
+		$params = "";
+		foreach ($param_array as $pair) {
+			
+			// register selector parameters
+			if (($register_selector) && ($pair["type"] == "SEL")) {
+				$params .= "sel_registerName(".$pair["name"]."), ";
+				continue;
+			}
+			
+			// use the object handle for NSObject descendants
+			if ($use_handle) {
+				if (in_array($pair["type"], $this->cocoa_classes)) {
+
+					// cast the param to the original class type
+					if ($cast_handle) {
+						if ($direct == ACCESS_HANDLE_DIRECT) {
+							$params .= $pair["type"]."(".$pair["name"].".Handle), ";
+						} else {
+							$params .= $pair["type"]."(GetHandle(".$pair["name"].")), ";
+						}
+					} else {
+						if ($direct == ACCESS_HANDLE_DIRECT) {
+							$params .= $pair["name"].".Handle, ";
+						} else {
+							$params .= "GetHandle(".$pair["name"]."), ";
+						}
+					}
+
+				} else {
+					if (($this->objects_are_wrappers) && ($pair["type"] == $this->objc_id)) {	// id is always a wrapper
+						if ($direct == ACCESS_HANDLE_DIRECT) {
+							$params .= $pair["type"]."(".$pair["name"].".Handle), ";
+						} else {
+							$params .= $pair["type"]."(GetHandle(".$pair["name"].")), ";
+						}
+					} else {
+						$params .= $pair["name"].", ";
+					}
+				}
+			} else { // append without modification
+				$params .= $pair["name"].", ";
+			}
+		}
+		
+		return trim($params, ", ");
+	}
+	
+	// Returns a list of paramameter variables with NS*** class types cast to "id" or the original class
+	function MakeObjcTypeParamList ($param_array, $objc_type) {
+		$params = "";
+		foreach ($param_array as $pair) {
+			if (in_array($pair["type"], $this->cocoa_classes)) {
+				if ($objc_type) {
+					$params .= "$this->objc_id(".$pair["name"]."), ";
+				} else {
+					$params .= $pair["type"]."(".$pair["name"]."), ";
+				}
+			} else {
+				$params .= $pair["name"].", ";
+			}
+		}
+		return trim($params, ", ");
+	}
+	
+	/**
+	 * PRINTING METHODS
+	 */
+															
+	// Prints all externally defined symbols
+	function PrintExternalSymbols ($header) {
+		if (!$this->dump[$header["name"]]["types"]) return;
+		foreach ($this->dump[$header["name"]]["types"] as $key => $type_array) {
+			
+			// External string constants
+			if ($key == "string_constant") {
+				$this->PrintOutput(0, "");
+				$this->PrintOutput(0, "{ External string constants }");
+				$this->PrintOutput(0, "var");
+				
+				foreach ($type_array as $type) $this->PrintOutput(1, $type);
+			}
+				
+			if ($key == "external_symbol") {
+				$this->PrintOutput(0, "");
+				$this->PrintOutput(0, "{ External symbols }");
+				$this->PrintOutput(0, "var");
+				
+				foreach ($type_array as $type) $this->PrintOutput(1, $type);
+			}
+		}
+	}
+	
+	// Prints all types in the header
+	function PrintTypes ($header) {
+		if (!$this->dump[$header["name"]]["types"]) return;
+		
+		foreach ($this->dump[$header["name"]]["types"] as $key => $type_array) {	
+			$section_printed = false;
+
+			// External defines
+			if ($key == "defines") {
+				
+				foreach ($type_array as $type) {
+					if (!$section_printed) {
+						$this->PrintOutput(0, "");
+						$this->PrintOutput(0, "{ Defines }");
+						$this->PrintOutput(0, "const");
+						$section_printed = true;
+					}
+					$this->PrintOutput(1, $type);
+				}
+			}
+							
+			// Enumerations
+			if ($key == "enums") {
+				$this->PrintOutput(0, "");
+				$this->PrintOutput(0, "{ Constants }");
+				foreach ($type_array as $block) {
+					$section_printed = false;
+					
+					foreach ($block as $type) {
+						if (!$section_printed) {
+							$this->PrintOutput(0, "");
+							$this->PrintOutput(0, "const");
+							$section_printed = true;
+						}
+
+						$this->PrintOutput(1, $type);
+					}
+				}
+			}
+			
+			// Typedefs		
+			if (($key == "typedef") || ($key == "named_enums")) {
+				foreach ($type_array as $type) {
+					if (!$section_printed) {
+						$this->PrintOutput(0, "");
+						$this->PrintOutput(0, "{ Types }");
+						$this->PrintOutput(0, "type");
+						$section_printed = true;
+					}
+					
+					$this->PrintOutput(1, $type);
+				}
+			}
+
+			// CallBacks
+			if ($key == "callbacks") {
+				foreach ($type_array as $name => $type) {
+					if (!$section_printed) {
+						$this->PrintOutput(0, "");
+						$this->PrintOutput(0, "{ Callbacks }");
+						$this->PrintOutput(0, "type");
+						$section_printed = true;
+					}
+					
+					$this->PrintOutput(1, "$name = $type");
+				}
+			}
+			
+		}
+	}
+	
+	// Prints all records in the header
+	function PrintRecords ($header) {
+		if (!$this->dump[$header["name"]]["types"]) return;
+		
+		foreach ($this->dump[$header["name"]]["types"] as $key => $type_array) {			
+			// Structures
+			if ($key == "structs") {
+				$this->PrintOutput(0, "");
+				$this->PrintOutput(0, "{ Records }");
+
+				foreach ($type_array as $type) {
+					$this->PrintOutput(0, "type");
+					$this->PrintOutput(1, $type);
+				}
+			}			
+		}
+	}
+		
+	// Prints all external functions in the header
+	function PrintFunctions ($header) {
+		if (!$this->dump[$header["name"]]["types"]) return;
+		
+		foreach ($this->dump[$header["name"]]["types"] as $key => $type_array) {	
+			if ($key == "functions") {
+				$this->PrintOutput(0, "");
+				$this->PrintOutput(0, "{ Functions }");
+				
+				foreach ($type_array as $type) $this->PrintOutput(0, $type);
+			}
+		}
+	}
+		
+	// Prints all classes from the header in reference format (not for compiling)
+	function PrintHeaderReference ($header, $path) {
+		
+		$this->output = fopen($path, "w+");
+		
+		//$this->PrintOutput(0, "{ ".ucfirst($header["framework"]).".framework ".$header["name"]." }");
+		$this->PrintOutput(0, "unit ".$header["name_clean"].";");
+		$this->PrintOutput(0, "interface");
+		$this->PrintOutput(0, "uses");
+		$this->PrintOutput(1, "ctypes, objc, MacOSAll, AnonClassDefinitions;");
+		
+		if ($header["classes"]) {
+			foreach ($header["classes"] as $class) {
+				$this->PrintOutput(0, "");
+				$this->PrintOutput(0, "type");
+				$this->PrintOutput(1, $class["name"]."Ref = ".$this->objc_id.";");
+				$this->PrintOutput(1, $class["name"]."Ptr = Pointer;");
+			}
+		}
+		
+		// types
+		$this->PrintTypes($header);
+		$this->PrintRecords($header);
+		$this->PrintFunctions($header);
+		$this->PrintExternalSymbols($header);
+		
+		if ($header["classes"]) {
+			
+			foreach ($header["classes"] as $class) {
+				if (in_array($class["name"], $this->cocoa_classes)) {
+					$this->PrintOutput(0, "");
+					$this->PrintOutput(0, "type");
+					
+					$this->PrintOutput(1, $class["name"]." = object(".$class["super"].")");
+
+					// print class-level methods
+					if (count($class["methods"]) > 0) {
+						$this->PrintOutput(0, "");
+						foreach ($class["methods"] as $method) {
+							$this->PrintOutput(2, $method["def"]);
+						}
+					}
+
+					// print category-level methods
+					if (count($class["categories"]) > 0) {
+						foreach ($class["categories"] as $name => $category) {
+							$this->PrintOutput(0, "");
+							$this->PrintOutput(2, "{ Category: $name }");
+
+							if ($category["methods"]) {
+								foreach ($category["methods"] as $method) {
+									$this->PrintOutput(2, $method["def"]);
+								}
+							}	
+						}
+					}
+					
+					$this->PrintOutput(1, "end;");
+				}
+			}
+		}
+		
+		// print procedural protocols
+		if ($header["protocols"]) {
+			foreach ($header["protocols"] as $protocol) {
+				if ($protocol["methods"]) {
+					$this->PrintOutput(0, "");
+					$this->PrintOutput(0, "{ Protocol: ".$protocol["name"]." }");
+
+					foreach ($protocol["methods"] as $name => $method) {
+						if ($method["kind"] != "constructor") {
+							$this->PrintProtocolDeclaration($protocol, $method);
+						}
+					}
+				}
+			}
+		}
+		
+		$this->PrintOutput(0, "");
+		$this->PrintOutput(0, "implementation");
+		$this->PrintOutput(0, "end.");
+	}
+		
+	// Merges two headers by difference
+	function MergeHeader ($header) {
+		/*
+		diff QLPreviewPanel_ORIGINAL.inc QLPreviewPanel_UPDATED.inc > diff.patch
+		patch QLPreviewPanel_ORIGINAL.inc -i diff.patch -o output.txt
+		
+		patch QLPreviewPanel.inc -i header.patch -o QLPreviewPanel.inc.merged
+		
+		also add -section="types,classes" which only prints into the sections and copies text from
+		the previous version if not specified
+		
+		*/
+		
+		// set the paths to use
+		$path = $header["path"];
+		$patch = "$this->root$this->out/$this->framework/header.patch";
+		$merged = $header["path_merge"];
+		
+		// create a patch using diff
+		exec("/usr/bin/diff \"$path\" \"$merged\" > \"$patch\"");
+		
+		// parse the diff file by mode
+		$lines = file($patch);
+		$content = "";
+		$section_lines = null;
+		$section_part = null;
+		$count = 0;
+		$section_id = 0;
+		//print_r($lines);
+		
+		if ($lines) {
+			foreach ($lines as $line) {
+				$count++;
+				
+				// remove line endings to aid regex
+				$line = trim($line, "\n");
+				
+				// parse section
+				if (($section_lines) && (!eregi("^[0-9]+", $line))) {
+					
+					// append line to section
+					$section_lines[] = "$line\n";
+					
+					// the section id is adding
+					if (eregi("^>", $line)) $section_part[$section_id] = true;
+					if (eregi("^<", $line)) $section_part[$section_id] = 0;
+
+					// section is changing type
+					if ($line == "---") {
+						$section_id++;
+						continue;
+					}
+				}
+				
+				// line is a new section or eof
+				if ((eregi("^[0-9]+", $line)) || ($count == count($lines))) {
+					
+					// append the section to the content
+					// we only accept sections where the first part (before ---) contains additions ">"
+					//print_r($section_part);
+					if (($section_part[0]) && (!$section_part[1])) $content .= implode($section_lines);
+
+					// init the new section
+					$section_lines = array();
+					$section_lines[] = "$line\n";
+					$section_id = 0;
+					$section_part = array(null, null);
+					
+					continue;
+				}
+				
+			}
+			
+			//print($content);
+			
+			// write the parsed patch back to the file
+			if ($content) {
+				file_put_contents($patch, $content);
+			} else {
+				$content = null;
+			}
+		}
+		
+		// patch the header to the merged file
+		if ($content) {
+			exec("/usr/bin/patch \"$path\" -i \"$patch\" -o \"$merged\" ");
+
+			// swap the contents of the merged file with the original
+			file_put_contents($path, file_get_contents($merged));
+		}
+		
+		// delete the temporary files
+		unlink($patch);
+		unlink($merged);
+	}
+
+  function PrintGlobalClassInfo($all_classes, $anon_classes) {
+    // for pascocoa: do nothing
+  }
+
+	// Prints all headers parsed
+	function PrintAllHeaders ($output_path, $ignore_output, $only_files, $print_header_references) {
+			
+			//print("• Printing ".count($this->dump)." headers...\n");
+			
+			foreach ($this->dump as $file => $header) {
+				
+				// the framework is set to not print, ignore the header
+				if (!$this->frameworks[$header["framework"]]["print"]) continue;
+
+				if (eregi("^[a-zA-Z0-9]+\.h", $file)) {
+					
+					// ignore these files
+					if (@in_array($header["path_partial"], $ignore_output)) continue;
+					
+					// only parse these files
+					if ((@count($only_files) > 0) && (@!in_array($header["name"], $only_files))) continue;
+					
+					$name_clean = substr($file, 0, (strripos($file, ".")));	
+					
+					// assign output path
+					if ($output_path != "") {
+						$header["path"] = $output_path."/".$name_clean.".inc";
+					}
+					
+					// print the header
+					$this->PrintHeader($header);
+					
+					// merge the headers
+					if (($this->merge_headers) && (!$this->show)) {
+						$this->MergeHeader($header);
+					}
+					
+					if ($print_header_references) $this->PrintHeaderReference($header, $this->root.$this->out."/reference/".$name_clean.".pas");
+					
+					if (!$this->show) print("* Printed $name_clean.h to ".$header["path"]."\n");
+				}
+			}
+			
+			// print global stuff (for Obj-P: a unit containing all classes as
+			// anonymous external classes, so they can be used before they are
+			// declared)
+			$this->PrintGlobalClassInfo($this->cocoa_classes, $this->defined_cocoa_classes, $this->anon_cocoa_classes);
+	}	
+	
+	/**
+	 * PARSING METHODS
+	 */
+
+	function GetAnonBitFieldName() {
+		$name = "_anonbitfield_".$this->current_header["name_clean"].$this->current_header["anonbitfields"];
+		$this->current_header["anonbitfields"]++;
+		return $name;
+	}
+	
+	function ParseNormalField($line, $protected_keywords, &$field_bitpacked, &$bitpacked_real_type, &$this_class_field_names) {
+		if (preg_match("!^\s*([^-{}*@+,<;:]*struct[^-*@+,<;:]+|[^-{}*@+,<;:]+)\b\s*(?:<([^>]*)>)?([*]*)\s*(\w+)((?:\s*,\s*[^:;[]+)*)?\s*(:[0-9]+)?\s*(\[.*\])?\s*(?:__attribute__\(\(([^)]*)\)\))?\s*;!", $line, $captures)) { // regular field
+					// captures[1]: type name (may be multiple words, and may not be complete
+					//              in case of an anonymous bitfield without a name)
+					//              Curly braces are only allowed in case of structs
+					// captures[2]: in case of id<protocol list>, the protocol list, empty
+					//              otherwise
+					// captures[3]: all pointer modifiers (*, **, ...), but only "*" and "**"
+					//              currently handled
+					// captures[4]: the field name (may be last part of type in case of
+					//              anonymous bit field, e.g. "unsigned long : 32")
+					// captures[5]: in case of multiple fields, the other field names (note
+					//              that things will go wrong if some of the fields in the
+					//							list are arrays/bitfields, that is only supported for
+					//							a single field)
+					// captures[6]: bitfield specification if any, empty otherwise
+					// captures[7]:	array specification if any, empty otherwise
+					// captures[8]: attributes if any, empty otherwise
+		
+					
+					if ($captures[3] != "") { // pointer type -> ok (cannot be wrongly interpreted)
+						$type = trim($captures[1]);
+						$pointertype = $captures[3];
+						$name = trim($captures[4]);
+		//				print("pointer field: $name: $pointertype $type\n");
+					} else {
+						// make sure we properly interpret stuff like "unsigned int :32"
+		//				print("regular: type = \"$captures[1]\", name = $captures[3]\n");
+						$pair = $this->ExtractCFieldSimpleTypeAndSingleName($captures[1]." ".$captures[4]);
+						$type = $pair["type"];
+						$name = $pair["name"];
+						if ($name == "") $name = $this->GetAnonBitFieldName(); 
+		//				print("regular field: \"$name\": $type\n");
+					}
+		//			print("field \"$name\": \"$type\", attr: $captures[8]\n");
+					
+					// if we have id <protocollist> and there's only one protocol in the
+					// in the list, we can replace id with the protocol
+					if (($type == "id") && ($captures[2] != "") && !strstr(",", $captures[2])) {
+		//				print("id<protocol>: $type -> $captures[2]Protocol\n");
+						$type = $captures[2]."Protocol";
+					}
+					// in case of "type field1, field2, field3", ", field2, field3" gets
+					// stored in othernames
+					$othernames = $captures[5];
+					$field_prefix = "";
+					
+					// Multiple Objective-C fields cannot have the same name, but they
+					// are case-insensitive and some only differ in case (only "reserved"
+					// fields until now, but that can change)
+					while (in_array(strtolower("$field_prefix$name"),$protected_keywords)) $field_prefix.="_";
+					if ($this_class_field_names != null) {
+						while (in_array(strtolower("$field_prefix$name"),$this_class_field_names)) $field_prefix.="_";
+					}
+					if ($this->IsKeywordReserved($field_prefix.$name)) $field_prefix .= "_";
+					// protect the name of these fields, in case there are methods with
+					// the same name
+					$this_class_field_names[] = strtolower($field_prefix.$name);
+					if ($othernames != "") {
+						$other_lower_case_names = preg_split("/\s*,\s*/",$othernames,-1,PREG_SPLIT_NO_EMPTY);
+						array_walk($other_lower_case_names,strtolowerref);
+						// should actually also check these for conflicts and add underscores if necessary
+					  $this_class_field_names = array_merge ($this_class_field_names, $other_lower_case_names);
+					}
+
+		/*
+					// we should also add prefixes to the other names if required, but my
+					// php-fu is too weak to replace the elements in original string
+					// efficiently, and this problem does not occur in the supported headers
+					foreach (explode($othernames, ",") as $othername) {
+						while (in_array(strtolower("$field_prefix$othername"),$protected_keywords)) $field_prefix.="_";
+						if ($this->IsKeywordReserved($field_prefix.$othernamename)) $field_prefix .= "_";
+						}
+		*/
+					// remove "struct" from the type
+					$type = preg_replace("!(\b)struct\b!","\1",$type);
+		
+					// clean/convert type			
+					$type = $this->ReplaceObjcType($type);
+					$bitpacked_real_type = $type;
+					$type = $this->MakeFieldBitPacked($type, $line, $field_bitpacked);
+					
+					// add pointer modifiers
+					$type = $this->EncodePointerModifiers($type,$pointertype);
+		
+					$field = "$field_prefix$name$othernames: $type";
+					if ($captures[8] && strstr("deprecated",$captures[8])) $field .= " deprecated";
+					$field .= ";";
+					$field = $this->MakeFieldInlineArray($field, $line, $name, $type);
+					$field = eregi_replace("<.*>", "", $field);
+					return $field;
+				}
+			return "";
+		}
+
+
+	function ParseInstanceVariables ($line, &$struct, $protected_keywords, &$this_class_field_names) {
+		$field = null;
+		$field_bitpacked = false;
+//		print("$line\n");
+			
+		// insert macros
+		if ($macro = $this->InsertMacroBlocks($line, $this->inside_macro_block)) {
+			if ($struct["valid"]) {
+				$struct["fields"][] = $macro;
+				return null;
+			} else {
+				return $macro;
+			}
+		}
+		
+		// got inline struct, probably a reference to a private struct
+		if (eregi("[[:space:]]*struct[[:space:]]+([a-zA-Z0-9_]+)[[:space:]]+\*([a-zA-Z0-9_]+)", $line, $captures)) {
+			if ($struct["valid"]) {
+				// ??? These don't compile as inline records which I thought they did...
+				//$struct["fields"][] = "$captures[1] = record end;";
+				//$struct["fields"][] = "$captures[1]Pointer = ^$captures[1];";
+				$struct["fields"][] = "$captures[2]: Pointer;";
+				$struct["ignore"][] = "$captures[2]";
+				return null;
+			} else {
+				//$fields = array();
+				//$fields[] = "$captures[1] = record end;";
+				//$fields[] = "$captures[1]Ptr = ^$captures[1];";
+				$field = "_$captures[2]: Pointer;";
+				return $field;
+			}
+		} 
+
+		// got struct
+		if (eregi("^[[:space:]]*struct.*{", $line)) {
+			$struct["valid"] = true;
+			$struct["ispsuedostruct"] = false;
+			$struct["fieldnames"] = array();
+			return null;
+		}
+		
+		// create an anonymous struct in case we have bitpacked fields without a
+		// surrounding struct
+		if (!$struct["valid"] && preg_match("!.*:[0-9]+\s*;!", $line)) {
+			$struct["valid"] = true;
+			$struct["ispsuedostruct"] = true;
+			$struct["fieldnames"] = array();
+		}
+
+		// end of bunch of bitfields -> go to normal mode again
+		if ($struct["ispsuedostruct"] && !preg_match("!.*:[0-9]+\s*;!", $line)) {
+			$struct["name"] = "_anoninternstruct_".$this->current_header["name_clean"].$this->current_header["anoninternstrucs"];
+			$this->current_header["anoninternstrucs"]++;
+			$struct["isfinished"] = true;
+			// make sure the current field isn't added anymore
+			$struct["valid"] = false;
+		}
+		
+		// end of struct
+		if (eregi("^[[:space:]]*}[[:space:]]*([a-zA-Z_0-9]+);", $line, $captures)) {
+			$struct["name"] = "_".trim($captures[1], " 	");
+			//print_r($struct);
+			$struct["isfinished"] = true;
+			return "struct";
+		}
+		
+		// set field prefix to protect scope
+		if (!$struct["valid"]) $field_prefix = "_";
+		
+		// remove null-defined macros: 
+		$line = str_ireplace($this->null_macros, "", $line);
+		
+		// replace garbage collector hints in the field	
+		$line = $this->ReplaceGarbageCollectorHints($line, $garbage_collector_hint);
+		
+		if (preg_match($this->pregex_function_pointer, $line, $captures)) { // function pointer
+//			print("function pointer: $line\n");
+			$field =$this->ParseFunctionDeclaration($captures[1], $captures[2], $captures[3], $captures[4], false, "");
+		} else {
+		  if (!$struct["valid"])
+		    $field = $this->ParseNormalField($line,$protected_keywords,$field_bitpacked,$bitpacked_real_type,$this_class_field_names);
+		  else
+		  	// don't register the names of fields of embedded structs and field names of the current
+		  	// class, but do track them for the current struct as there may be conflicts due to
+		  	// Pascal's case-insensitivity
+		    $field = $this->ParseNormalField($line,$protected_keywords,$field_bitpacked,$bitpacked_real_type,$struct["fieldnames"]);
+		}
+
+		// mark the field as having a garbage collector field
+		if ($garbage_collector_hint) $field = "$field {garbage collector: $garbage_collector_hint }";
+		
+		// return field
+		if ($struct["valid"]) {
+			if (!$struct["bitpacked"]) $struct["bitpacked_first_type"] = $bitpacked_real_type;
+			if ($field_bitpacked) $struct["bitpacked"] = true;
+			$struct["fields"][] = $field;
+		} else {
+			return $field;
+		}
+	}
+	
+	// Parses $line into a function declaration string. Handles both
+	// function pointers (isexternfunc = false) and external functions
+	// (isexternfunc = true)
+	function ParseFunctionDeclaration($rettypestr, $retpointertypestr, $funcname, $parastr, $isexternfunc, $deprecatedmods) {
+	  
+	  if ($deprecatedmods != "") $deprecatedmods .= ";";
+		if ($this->IsKeywordReserved($funcname)) $funcname .= "_";
+	  
+	  $rettype = trim(str_replace_word("const","",$rettypestr));
+		$rettype = $this->ReplaceObjcType($rettype);
+		$rettype = $this->EncodePointerModifiers($rettype,$retpointertypestr);
+		$params = $this->ConvertCParamsPascal($parastr);
+
+		if ($rettype == "void")
+			$result = "procedure ";
+		else
+			$result = "function ";
+	  
+		// if no name specified, the caller will add it
+		if ($funcname != "") {
+			if (!$isexternfunc)
+				$result = "$funcname: " . $result;
+			else
+				$result .= $funcname;
+		}
+
+		if ($params != "") $params = "(" . $params . ")";
+		if ($rettype == "void")
+			$result .= $params . "; cdecl;";
+		else
+			$result .= $params . ": " . $rettype . "; cdecl;";
+	  
+	  if ($isexternfunc)
+	  	$result .= " external;$deprecatedmods";
+	  else
+	  	$result .= "\n";
+	  
+	  return $result;
+	}
+	
+	// Parses $line into the combined $struct_fields string
+	function ParseStructFields ($line, $protected_keywords, &$struct_fields, &$found_any_bitpacked, &$all_bitpacked, &$first_bitpacked_type) {
+		if (preg_match($this->pregex_function_pointer, $line, $captures)) {
+			$struct_fields .= "    " . $this->ParseFunctionDeclaration($captures[1], $captures[2], $captures[3], $captures[4], false, "");
+			$all_bitpacked = false;
+		} else {
+			// better: keep for entire struct, so we can escape conflicting names due to
+			// case-insensitivity
+		  $tempnewprotected = array();
+			$new_field = $this->ParseNormalField($line,$protected_keywords,$field_bitpacked,$bitpacked_real_type,$tempnewprotected);
+//			print("field: '$new_field', bitpacked: $field_bitpacked, any: $found_any_bitpacked, all: $all_bitpacked\n");
+			if ($new_field != "") {
+				$found_any_bitpacked |= $field_bitpacked;
+				if ($struct_fields == "") {
+					$all_bitpacked = $field_bitpacked;
+					$first_bitpacked_type = $bitpacked_real_type;
+				}
+				else $all_bitpacked &= $field_bitpacked;
+				$struct_fields .= "    " . $new_field . $this->AppendEOLComment() . "\n";
+			}
+//			print("  after: any: $found_any_bitpacked, all: $all_bitpacked\n");
+		}
+	}
+	
+	// Parse a single enum field
+	function ParseEnumFields ($line, $file_name, &$block_count, &$auto_increment) {
+		
+		// insert macros
+		//if ($macro = $this->InsertMacroBlocks($line, $this->inside_macro_block)) $this->dump[$file_name]["types"]["enums"][$block_count][] = $macro;
+
+		if (ereg("^[[:space:]]*[,]*[[:space:]]*([a-zA-Z0-9_]+)[[:space:]]*=[[:space:]]*[(]*([a-zA-Z_]+)[)]*[,]*[[:space:]]*$", $line, $captures)) { // string value
+			$captures[2] = trim($captures[2], ", ");
+			$this->dump[$file_name]["types"]["enums"][$block_count][] = $captures[1]." = ".$captures[2].";".$this->AppendEOLComment();
+		} elseif (ereg("^[[:space:]]*[,]*[[:space:]]*([a-zA-Z0-9_]+)[[:space:]]*=[[:space:]]*[(]*([0-9-]+)[)]*[,]*[[:space:]]*$", $line, $captures)) { // integer value
+			$captures[2] = trim($captures[2], ", ");
+			$this->dump[$file_name]["types"]["enums"][$block_count][] = $captures[1]." = ".$captures[2].";".$this->AppendEOLComment();
+		} elseif (ereg("^[[:space:]]*[,]*[[:space:]]*([a-zA-Z0-9_]+)[[:space:]]*=[[:space:]]*[(]*([0-9]+[xX]+[a-fA-F0-9]+)[)]*", $line, $captures)) { // hexadecimal value
+			$captures[2] = trim($captures[2], ", ");
+			$captures[2] = eregi_replace("^0x", "$", $captures[2]);
+			$this->dump[$file_name]["types"]["enums"][$block_count][] = $captures[1]." = ".$captures[2].";".$this->AppendEOLComment();
+		} elseif (ereg("^[[:space:]]*[,]*[[:space:]]*([a-zA-Z0-9_]+)[[:space:]]*=[[:space:]]*([a-zA-Z0-9]+[[:space:]]*<<[[:space:]]*[a-zA-Z0-9]+)", $line, $captures)) { // << shl value, no ()
+			$captures[2] = ereg_replace("[[:space:]]?<<[[:space:]]?", " shl ", $captures[2]);
+			
+			// remove integer type hints
+			$captures[2] = ereg_replace("([0-9]+)[UL]+([[:space:]]+)shl([[:space:]])", "\\1\\2shl\\3", $captures[2]);
+			$captures[2] = ereg_replace("([[:space:]])shl([[:space:]]+)([0-9]+)[UL]+", "\\1shl\\2\\3", $captures[2]);
+
+			$this->dump[$file_name]["types"]["enums"][$block_count][] = $captures[1]." = ".$captures[2].";".$this->AppendEOLComment();
+		} elseif (ereg("^[[:space:]]*[,]*[[:space:]]*([a-zA-Z0-9_]+)[[:space:]]*=[[:space:]]*\(([a-zA-Z0-9]+[[:space:]]*<<[[:space:]]*[a-zA-Z0-9]+)\)", $line, $captures)) { // << shl value
+			$captures[2] = trim($captures[2], ", ");
+			$captures[2] = ereg_replace("[[:space:]]?<<[[:space:]]?", " shl ", $captures[2]);
+			
+			// remove integer type hints
+			$captures[2] = ereg_replace("([0-9]+)[UL]+([[:space:]]+)shl([[:space:]])", "\\1\\2shl\\3", $captures[2]);
+			$captures[2] = ereg_replace("([[:space:]])shl([[:space:]]+)([0-9]+)[UL]+", "\\1shl\\2\\3", $captures[2]);
+
+			$this->dump[$file_name]["types"]["enums"][$block_count][] = $captures[1]." = ".$captures[2].";".$this->AppendEOLComment();
+		} elseif (ereg("^[[:space:]]*[,]*[[:space:]]*([a-zA-Z0-9_]+)[[:space:]]*[,}]*[[:space:]]*$", $line, $captures)) { // non-value
+			
+			// omit lines which started nested structures.
+			// bad practice but the single-line regex parser can't handle them
+			if (!eregi("[=|]+", $line)) {
+				$captures[1] = trim($captures[1], ", ");
+				$this->dump[$file_name]["types"]["enums"][$block_count][] = $captures[1]." = ".$auto_increment.";";
+				$auto_increment ++;
+			}
+		}
+	}
+
+	// create a variant record with a first anonymous field of type
+	// first_bitpacked_type so that the compiler may correctly align it
+	// (it does not do that currently, but this at least provides a
+	//  hint to the programmer)
+	function BitPackedForceAlignment($first_bitpacked_type, $firstindent, $otherindents) {
+		$result = $firstindent . "case byte of\n" . $otherindents ."0: (" . $this->GetAnonBitFieldName() . ": $first_bitpacked_type);\n" . $otherindents . "1: (";
+		return $result;
+	}
+
+	// Parse external symbols, enums and typedef's from the header
+	function ParseHeaderTypes ($file) {
+			$contents = ReadTextFile($file);
+			$file_name = substr($file, (strripos($file, "/")) + 1, strlen($file));	
+			$any_field_bitpacked = false;
+			$all_fields_bitpacked = false;
+			
+			// reset comments from previous parsing sections
+			$this->ResetComment();
+			
+			$lines = explode("\n", $contents);
+			foreach ($lines as $line) {
+				
+				// skip blocks
+				if ($this->SkipBlock($line)) continue;
+				
+				// ignore lines
+				if (in_array($line, $this->ignore_lines)) continue;
+				
+				// build comments
+				$this->BuildComment($line, $file_name);
+				
+				// build macro blocks
+				$this->BuildMacroBlocks($line);
+				
+				// garbage collector hints
+				$line = $this->ReplaceGarbageCollectorHints($line, $garbage_collector_hint);
+					
+				// remove macros	
+				$line = $this->RemoveVersionMacros($line, $deprecatedmods);
+				
+				// remove comments
+				$line = $this->RemoveComments($line);
+				$line = trim($line, " ");
+									
+				if ($got_struct) {
+					
+					// insert macros
+					if ($macro = $this->InsertMacroBlocks($line, $this->inside_macro_block)) $struct_fields .= "$macro\n";
+					
+					// collect fields
+					$this->ParseStructFields($line, array(), $struct_fields, $any_field_bitpacked, $all_fields_bitpacked, $first_bitpacked_type);
+					
+					// got end of struct
+					if (ereg("^}[[:space:]]*([a-zA-Z_0-9]+);", $line, $captures)) {
+						
+						if ($struct_name == "") {
+							$struct_name = $captures[1];
+						} else {
+							$struct_type = $captures[1];
+						}
+						
+						// ignore this struct
+						if (in_array($struct_name, $this->ignore_types)) continue;
+						
+						if ($all_fields_bitpacked) {
+							$struct = "$struct_comment$struct_name = $this->bitpacked_record_keyword\n";
+							$struct .= $this->BitPackedForceAlignment($first_bitpacked_type, "    ", "    ") . "\n";
+							$struct_fields = str_replace("    ","          ",$struct_fields);
+							$struct_fields .= "       );\n";
+						} else {
+							$struct = "$struct_comment$struct_name = $this->record_keyword\n";
+						}
+						
+						$struct .= $struct_fields;
+						$struct .= "  end$deprecatedmods;\n";
+						if (($struct_type) && ($struct_name != $struct_type)) {
+							$struct .= "$struct_type = $struct_name;\n";
+						}
+						// pointer type
+						$struct .= $struct_name."Ptr = ^".$struct_name.";\n";
+						
+						$this->dump[$file_name]["types"]["structs"][] = $struct;
+						$this->dump["global_structs"][] = $struct_name;
+						$got_struct = false;
+						$any_field_bitpacked = false;
+						$all_fields_bitpacked = false;
+					}
+				}
+				
+				// got single-line struct
+				if (ereg("^typedef[[:space:]]+struct[[:space:]]+{(.*)}[[:space:]]+([a-zA-Z0-9_]+)", $line, $captures)) {
+					$struct_name = trim($captures[2], " ");
+					if (!in_array($struct_name, $this->ignore_types)) {
+						
+
+						// break the struct into lines
+						$single_struct_fields = "";
+						$fields = explode(";", $captures[1]);
+						$comment = $this->InsertCurrentComment();
+						$this->ResetComment();
+						
+						// parse each line
+						foreach ($fields as $field) {
+							$field = trim($field);
+							$this->ParseStructFields($field.";", array(), $single_struct_fields, $any_field_bitpacked, $all_fields_bitpacked, $first_bitpacked_type);
+						}
+						
+						// merge the fields into the definition
+						$struct = "$comment\n"."$struct_name = ";
+						if ($all_fields_bitpacked) {
+							$struct .= "$this->bitpacked_record_keyword\n";
+							$struct .= $this->BitPackedForceAlignment($first_bitpacked_type, "    ", "    ") . "\n";
+							$single_struct_fields = str_replace("    ","          ",$single_struct_fields);
+							$single_struct_fields .= "       );\n";
+						}	else $struct .= "$this->record_keyword\n";
+						$struct .= $single_struct_fields;
+						$struct .= "  end$deprecatedmods;\n";
+						// pointer type
+						$struct .= $struct_name."Ptr = ^".$struct_name.";\n";
+						
+						$this->dump[$file_name]["types"]["structs"][] = $struct;
+						$this->dump["global_structs"][] = $struct_name;
+						$any_field_bitpacked = false;
+						$all_fields_bitpacked = false;
+						//print("$single_struct_fields\n");
+					}
+				// got begin of struct
+				} elseif (ereg("^typedef struct(.*){", $line, $captures)) {
+					$struct_name = trim($captures[1], " ");
+					if (!in_array($struct_name, $this->ignore_types)) {
+						$struct_type = null;
+						$struct_fields = "";
+						$struct_comment = $this->InsertCurrentComment();
+						$this->ResetComment();
+						if ($struct_comment != "") $struct_comment = "$struct_comment\n";
+						$got_struct = true;
+					}
+				}
+
+				// got function pointer type
+				if (preg_match($this->pregex_function_pointer_typedef, $line, $captures)) {
+					
+					$typestr = $this->ParseFunctionDeclaration($captures[1], $captures[2], "", $captures[6], false, $deprecatedmods);
+					$functypename = $captures[7];
+					if ($functypename == "") $functypename = $captures[5];
+					if ($functypename == "") $functypename = $captures[4];
+					$this->dump[$file_name]["types"]["callbacks"][$functypename] = $typestr;
+					// record if it is a function type instead of a function pointer type
+					if ($captures[3] == "") $this->implicit_function_pointer_types[] = $functypename;
+
+					continue;
+				}
+				
+				// #defines
+				$got_define = false;
+				if (ereg("#[[:space:]]*define[[:space:]]+([a-zA-Z0-9_]+)[[:space:]]+\(\(.*\)(.*)\)", $line, $captures)) { // named constant with type case
+					$got_define = true;
+				} elseif (ereg("#[[:space:]]*define[[:space:]]+([a-zA-Z0-9_]+)[[:space:]]+[(]*([0-9.-]+)[)]*", $line, $captures)) { //integer
+					$got_define = true;
+				}
+				
+				if ($got_define) {
+					$define_name = $captures[1];
+					if (!in_array($define_name, $this->ignore_types)) {
+						$define_name = $this->ReplaceObjcType($define_name);
+						//if ($this->comment_terminated) $this->dump[$file_name]["types"]["defines"][] = $this->InsertCurrentComment();
+						$this->AppendCurrentComment($this->dump[$file_name]["types"]["defines"]);
+						$this->dump[$file_name]["types"]["defines"][] = $define_name." = ".$captures[2].";".$this->AppendEOLComment();
+					} else {
+						$this->ResetComment();
+					}
+				}
+								
+				// parse enum fields
+				if (($got_enum) || ($got_named_enum)) {
+					// print($line."\n");
+					
+					$this->ParseEnumFields($line, $file_name, &$block_count, &$auto_increment);
+
+					// found the end
+					if (ereg("^};", $line)) $got_enum = false;
+				}
+				
+				// ==== got inline named enum ===
+				if (ereg("^[[:space:]]*enum[[:space:]]+([a-zA-Z0-9_]+)[[:space:]]*{(.*)};", $line, $captures)) {
+					//print("$line\n");
+					
+					$enum_name = trim($captures[1], " ");
+					if (!in_array($enum_name, $this->ignore_types)) {
+						
+						$block_count ++;
+						$auto_increment = 0;
+
+						// break the enum into lines
+						$fields = explode(",", $captures[2]);
+						//$this->AppendCurrentMacro($this->dump[$file_name]["types"]["enums"][$block_count]);
+						$this->AppendCurrentComment($this->dump[$file_name]["types"]["enums"][$block_count]);
+						if ($this->comment_terminated) $this->dump[$file_name]["types"]["enums"][$block_count][] = $this->InsertCurrentComment();
+						$this->ResetComment();
+						
+						// parse each line
+						foreach ($fields as $field) {
+							$field = trim($field, " ");
+							$this->ParseEnumFields($field.",", $file_name, &$block_count, &$auto_increment);
+						}
+					}
+					
+					continue;
+				}
+
+				// ==== got inline enum ===
+				if (ereg("^[[:space:]]*enum[[:space:]]*{(.*)};", $line, $captures)) {
+					//print("$line\n");
+					
+					$block_count ++;
+					$auto_increment = 0;
+
+					// break the enum into lines
+					$fields = explode(",", $captures[1]);
+					$this->AppendCurrentComment($this->dump[$file_name]["types"]["enums"][$block_count]);
+					//if ($this->comment_terminated) $this->dump[$file_name]["types"]["enums"][$block_count][] = $this->InsertCurrentComment();
+					$this->ResetComment();
+					
+					// parse each line
+					foreach ($fields as $field) {
+						$field = trim($field, " ");
+						$this->ParseEnumFields($field.",", $file_name, &$block_count, &$auto_increment);
+					}
+					
+					continue;
+				}
+				
+				// ==== got enum ===
+				if (ereg("^enum", $line)) {
+					$got_enum = true;
+					$block_count ++;
+					$auto_increment = 0;
+					$this->AppendCurrentComment($this->dump[$file_name]["types"]["enums"][$block_count]);
+					//if ($this->comment_terminated) $this->dump[$file_name]["types"]["enums"][$block_count][] = $this->InsertCurrentComment();
+				}
+				
+				// terminate named enum
+				if ($got_named_enum) {
+					if (ereg("^}[[:space:]]*([a-zA-Z0-9_]+);", $line, $captures)) {
+						$got_named_enum = false;
+						
+						$named_enum = trim($named_enum, ", \n");
+						$name = $captures[1];
+						
+						if (!in_array($name, $this->ignore_types)) {
+							$this->dump[$file_name]["types"]["named_enums"][] = "$name = culong;";
+							$this->dump["global_types"][$name] = $name;
+						}
+					}
+				}
+
+				// ==== got named enum ===
+				if (ereg("^typedef enum {", $line)) {
+					$got_named_enum = true;
+					$named_enum = "";
+					$auto_increment = 0;
+					$block_count ++;
+					$this->AppendCurrentComment($this->dump[$file_name]["types"]["named_enums"][$block_count]);
+					//if ($this->comment_terminated) $this->dump[$file_name]["types"]["named_enums"][] = $this->InsertCurrentComment();
+				}
+				
+				// ==== external functions ===
+				// doesn't work when $this->external_string_macros is added to
+				// the string at initialisation time, because it can still change
+				// later (while loading frameworks.xml)
+				if (preg_match("!^(?:$this->external_string_macros)+".$this->pregex_external_function_end, $line, $captures)) {
+				
+					// ignore symbols
+					if (in_array($captures[3], $this->ignore_types)) continue;
+
+					$typestr = $this->ParseFunctionDeclaration($captures[1], $captures[2], $captures[3], $captures[4], true, $deprecatedmods);
+					
+					$this->dump[$file_name]["types"]["functions"][] = $typestr;
+					continue;
+				}
+				
+				// ==== external string constant ===
+				if (eregi("^($this->external_string_macros)+[[:space:]]+NSString[[:space:]]*\*[[:space:]]*(const)*[[:space:]]*([a-zA-Z0-9_]+)", $line, $captures)) {
+					$name = $captures[3];
+					
+					if (in_array($name, $this->ignore_types)) continue;
+					
+					// insert comments
+					$this->AppendCurrentComment($this->dump[$file_name]["types"]["string_constant"]);
+					//if ($this->comment_terminated) $this->dump[$file_name]["types"]["string_constant"][] = $this->InsertCurrentComment();
+					
+					$this->dump[$file_name]["types"]["string_constant"][] = "$name: $this->string_macro$deprecatedmods; cvar; external;";
+				}
+				
+				// ==== external symbol ===
+				if (eregi("^($this->external_string_macros)+[[:space:]]+([a-zA-Z0-9_ ]+)[[:space:]]+([a-zA-Z0-9_]+)", $line, $captures)) {
+					$name = $captures[3];
+					$type = $captures[2];
+					
+					// ignore symbols
+					if (in_array($name, $this->ignore_types)) continue;
+					
+					$type = istr_replace_word("const", "", $type);
+					$type = $this->ReplaceObjcType(trim($type, " "));
+					
+					
+					$this->AppendCurrentComment($this->dump[$file_name]["types"]["external_symbol"]);
+					//if ($this->comment_terminated) $this->dump[$file_name]["types"]["external_symbol"][] = $this->InsertCurrentComment();
+					$this->dump[$file_name]["types"]["external_symbol"][] = "$name: $type$deprecatedmods; cvar; external;";
+				}
+								
+				// ==== got typedef ===
+				if (ereg("^typedef[[:space:]]+struct[[:space:]]+([a-zA-Z0-9_]+)[[:space:]]+([a-zA-Z0-9_]+);", $line, $captures)) { // defined struct type
+					$real_type = $captures[1];
+					$struct_type = $captures[1];
+					$new_type = $captures[2];
+					
+					// ignore types
+					if (in_array($struct_type, $this->ignore_types)) continue;
+					if (in_array($new_type, $this->ignore_types)) continue;
+					
+					$this->AddTypeDef($this->dump[$file_name], "$struct_type = record end$deprecatedmods;");
+					
+					$struct_type = $this->ReplaceObjcType($struct_type);
+					if ($new_type != $struct_type) {
+						$this->AddTypeDef($this->dump[$file_name], "$new_type = $struct_type$deprecatedmods;");
+						$this->dump["global_types"][$new_type] = $real_type;
+					}
+					$this->opaque_structs[] = $struct_type;
+					
+					// also add pointer type to the opaque struct
+					$this->AddTypeDef($this->dump[$file_name], $new_type."Ptr = ^$new_type$deprecatedmods;");
+					
+					$this->dump["global_types"][$struct_type] = "record end";
+					$this->dump["global_types"][$new_type."Ptr"] = "^".$new_type;
+				} elseif (ereg("^typedef[[:space:]]+struct[[:space:]]+([a-zA-Z0-9_]+)[[:space:]]+([a-zA-Z0-9_*]+);", $line, $captures)) { // pointer to struct
+					$real_type = $captures[1];
+					$clean_name = trim($captures[2], "*");
+					$pointer_type = $captures[1];
+					
+					// ignore types
+					if (in_array($clean_name, $this->ignore_types)) continue;
+					
+					$pointer_type = "Pointer";
+					$this->AddTypeDef($this->dump[$file_name], "$clean_name = $pointer_type$deprecatedmods;");
+					
+					$this->dump["global_types"][$clean_name] = $real_type;
+
+					// also add pointer type
+					$this->AddTypeDef($this->dump[$file_name], $clean_name."Ptr = ^$clean_name$deprecatedmods;");
+					$this->dump["global_types"][$clean_name."Ptr"] = "^".$clean_name;
+
+				} elseif (ereg("^typedef[[:space:]]+(const)*[[:space:]]*struct[[:space:]]+([a-zA-Z0-9_*]+)[[:space:]]+([a-zA-Z0-9_]+);", $line, $captures)) { // struct type (complex)
+					$real_type = $captures[1];
+					$typedef_name = $captures[3];
+					
+					// ignore types
+					if (in_array($typedef_name, $this->ignore_types)) continue;
+					
+					$captures[2] = $this->FormatObjcType($captures[2], $modifiers);
+					$this->AddTypeDef($this->dump[$file_name], $typedef_name." = ".$captures[2].$deprecatedmods.";");
+					
+					$this->dump["global_types"][$typedef_name] = $real_type;
+
+					// also add pointer type
+					$this->AddTypeDef($this->dump[$file_name], $typedef_name."Ptr = ^$typedef_name$deprecatedmods;");
+					$this->dump["global_types"][$typedef_name."Ptr"] = "^".$typedef_name;
+				} elseif (ereg("^typedef[[:space:]]+([a-zA-Z0-9_]+)[[:space:]]+([a-zA-Z0-9_*]+);", $line, $captures)) { // single-word type
+					$real_type = $captures[1];
+					
+					// type is a pointer
+					if ($captures[2][0] == "*") {
+						$captures[2] = trim($captures[2], "*");
+						$captures[1] = $this->ReplaceObjcType($captures[1]);
+						
+						// ignore types
+						if (in_array($captures[2], $this->ignore_types)) continue;
+						
+						$this->AddTypeDef($this->dump[$file_name], $captures[2]." = ^".$captures[1]."$deprecatedmods;");
+						
+						$this->dump["global_types"][$captures[2]] = $real_type;
+
+					} else {
+						$captures[2] = trim($captures[2], "*");
+						$captures[1] = $this->ReplaceObjcType($captures[1]);
+						
+						// ignore types
+						if (in_array($captures[2], $this->ignore_types)) continue;
+												
+						$this->AddTypeDef($this->dump[$file_name],$captures[2]." = ".$captures[1]."$deprecatedmods;");
+					}
+					// also add pointer type
+					$this->AddTypeDef($this->dump[$file_name], $captures[2]."Ptr = ^$captures[2]$deprecatedmods;");
+					$this->dump["global_types"][$captures[2]."Ptr"] = "^".$captures[2];
+				} elseif (ereg("^typedef[[:space:]]+([a-zA-Z0-9_]+)[[:space:]]+([a-zA-Z0-9_]+)[[:space:]]+([a-zA-Z0-9_*]+);", $line, $captures)) { // double-word type
+					$real_type = $captures[1];
+					
+					$typedef_name = trim($captures[3], "*");
+					$long_type = $captures[1]." ".$captures[2];
+					$long_type = $this->ReplaceObjcType($long_type);
+					
+					// ignore types
+					if (in_array($captures[2], $this->ignore_types)) continue;
+					
+					$this->AddTypeDef($this->dump[$file_name], $typedef_name." = $long_type$deprecatedmods;");
+					
+					$this->dump["global_types"][$typedef_name] = $real_type;
+
+					// also add pointer type
+					$this->AddTypeDef($this->dump[$file_name], $typedef_name."Ptr = ^$typedef_name$deprecatedmods;");
+					$this->dump["global_types"][$typedef_name."Ptr"] = "^".$typedef_name;
+				}
+			}
+			
+		//print_r($this->dump[$file_name]["types"]);
+	}	
+	
+	// Parse all protocols in a header
+	function ParseHeaderProtocols ($file) {
+			$contents = ReadTextFile($file);
+			$file_name = substr($file, (strripos($file, "/")) + 1, strlen($file));
+			
+			// reset comments from previous parsing sections
+			$this->ResetComment();
+			
+			$lines = explode("\n", $contents);
+			foreach ($lines as $line) {
+							
+				// skip blocks
+				if ($this->SkipBlock($line)) continue;
+						
+				// ignore lines
+				if (in_array($line, $this->ignore_lines)) continue;
+										
+				// remove macros	
+				$line = $this->RemoveVersionMacros($line, $deprecatedmods);
+															
+				// build comments
+				if (!$got_got_protocol) $this->BuildComment($line, $file_name);
+							
+				// parse protocol
+				if ($got_protocol) {
+					
+					// build comments
+					$this->BuildComment($line, $file_name);
+					
+					// remove comments
+					$line = $this->RemoveComments($line);
+					
+					// found property
+					if ($this->LineHasProperty($line, $captures)) {
+							$properties = $this->ParseClassProperty($current_protocol, $captures, $deprecatedmods);
+							
+							foreach ($properties as $property) {
+								if ($property["setter"]) {
+									$property["setter"]["comment"] = $this->InsertCurrentComment();
+									$this->current_header["protocols"][$current_protocol]["methods"][$property["setter"]["objc_method"]] = $property["setter"];
+							
+									// append to master list of protocols
+									$this->dump["protocols"][$current_protocol][] = $property["setter"];
+								}
+							
+								if ($property["getter"]) {
+									$property["getter"]["comment"] = $this->InsertCurrentComment();
+									$this->current_header["protocols"][$current_protocol]["methods"][$property["getter"]["objc_method"]] = $property["getter"];
+							
+									// append to master list of protocols
+									$this->dump["protocols"][$current_protocol][] = $property["getter"];
+								}
+							}
+						
+							continue;
+					}
+					
+					// found method
+					$method = null;
+					if (eregi($this->regex_objc_method_params, $line, $captures)) {
+						$method = $this->ConvertObjcMethodToPascal($current_protocol, $line, $captures, array(), true, $deprecatedmods);	
+					} elseif (eregi($this->regex_objc_method_no_params, $line, $captures)) {
+						$method = $this->ConvertObjcMethodToPascal($current_protocol, $line, $captures, array(), false, $deprecatedmods);
+					} elseif (eregi($this->regex_objc_method_partial, $line, $captures)) {
+						$method_fragment = $line;
+					}
+
+					// append to classes
+					if (($method) /* && (!in_array($method["name"], $this->ignore_methods))*/ ) {
+						
+						// add comment to the method
+						$method["comment"] = $this->InsertCurrentComment();
+						
+						$this->current_header["protocols"][$current_protocol]["methods"][$method["objc_method"]] = $method;
+						
+						// append to master list of protocols
+						$this->dump["protocols"][$current_protocol][] = $method;
+					}
+					
+					// found the end
+					if (ereg("^@end", $line)) {
+						$this->ResetComment();
+						$got_protocol = false;
+					}
+				}
+				
+				// got protocol
+				if ((eregi($this->regex_objc_protocol, $line, $captures)) && (!eregi(".*;$", $line))) {
+						$got_protocol = true;
+						$current_protocol = $captures[1];
+						print("+ Protocol $current_protocol\n");
+						
+						if ($this->comment_terminated) $this->current_header["protocols"][$current_protocol]["comment"] = $this->InsertCurrentComment();
+						$this->current_header["protocols"][$current_protocol]["name"] = $captures[1];
+				}
+			}
+			
+		//print_r($this->current_class);
+	}
+	
+	
+	// Parse all categories in a header
+	function ParseHeaderCategories ($file) {
+			$contents = ReadTextFile($file);
+			$file_name = substr($file, (strripos($file, "/")) + 1, strlen($file));
+			
+			// reset comments from previous parsing sections
+			$this->ResetComment();
+			
+			$lines = explode("\n", $contents);
+			foreach ($lines as $line) {
+
+				// skip blocks
+				if ($this->SkipBlock($line)) continue;
+
+				// ignore lines
+				if (in_array($line, $this->ignore_lines)) continue;
+
+				// remove macros	
+				$line = $this->RemoveVersionMacros($line, $deprecatedmods);
+
+				// build comments
+				if (!$got_category) $this->BuildComment($line, $file_name);
+				
+				// parse category
+				if ($got_category) {
+					
+					// build comments
+					$this->BuildComment($line, $file_name);
+					
+					// remove comments
+					$line = $this->RemoveComments($line);
+					
+					// found property
+					if ($this->LineHasProperty($line, $captures)) {
+							$properties = $this->ParseClassProperty($current_category, $captures, $deprecatedmods);
+
+							if (!in_array($current_category, $this->ignore_categories)) {
+								foreach ($properties as $property) {
+									if ($property["setter"]) {
+										if ($this->AddMethodToClass($property["setter"], $this->current_class)) {
+											$this->dump[$category_owner]["classes"][$current_class]["categories"][$current_category]["methods"][] = $property["setter"];
+											$this->dump[$category_owner]["categories"][$current_category]["methods"][] = $property["setter"];
+										}
+									}
+								
+									if ($property["getter"]) {
+										if ($this->AddMethodToClass($property["getter"], $this->current_class)) {
+											$this->dump[$category_owner]["classes"][$current_class]["categories"][$current_category]["methods"][] = $property["getter"];
+											$this->dump[$category_owner]["categories"][$current_category]["methods"][] = $property["getter"];
+										}
+									}
+								}
+						  }
+							continue;
+					}
+					
+					// build method fragment
+					if ($method_fragment) $method_fragment .= " ".trim($line);
+					
+					// found method fragment termination
+					if (($method_fragment) && (eregi($this->regex_objc_method_terminate, $line))) {
+						$line = $method_fragment;
+						$method_fragment = null;
+					}
+					
+					// found method
+					$method = null;
+					if (eregi($this->regex_objc_method_params, $line, $captures)) {
+						$method = $this->ConvertObjcMethodToPascal($current_category, $line, $captures, $this->GetProtectedKeywords($this->current_class), true, $deprecatedmods);						
+					} elseif (eregi($this->regex_objc_method_no_params, $line, $captures)) {
+						$method = $this->ConvertObjcMethodToPascal($current_category, $line, $captures, $this->GetProtectedKeywords($this->current_class), false, $deprecatedmods);	
+					} elseif (eregi($this->regex_objc_method_partial, $line, $captures)) {
+						$method_fragment = $line;
+					}
+					
+					// append to classes
+					if (($method) && !in_array($current_category, $this->ignore_categories)) {
+						if ($current_class) {
+							if ($this->AddMethodToClass($method, $this->current_class)) {
+								$this->dump[$category_owner]["classes"][$current_class]["categories"][$current_category]["methods"][] = $method;
+								$this->dump[$category_owner]["categories"][$current_category]["methods"][] = $method;
+							}
+						}
+						
+					}
+					
+					// found the end
+					if (ereg("^@end", $line)) {
+						$got_category = false;
+						continue;
+					}
+				}
+				
+				// got category
+				if (eregi($this->regex_objc_category, $line, $captures)) {
+					
+					$got_category = true;
+					$category_owner = $file_name;
+					$category_name = $captures[2];
+					$current_class = $captures[1];
+					$current_category = $category_name;
+
+					if (!in_array($current_category, $this->ignore_categories)) {
+						// Protect category names against duplicate identifiers by appending the class it extends to the name
+						if ((count($this->dump["categories"][$current_category]) > 0) || (in_array($category_name, $this->cocoa_classes))) {
+							$current_category = $category_name."_".$current_class;
+							$this->dump[$file_name]["categories"][$current_category]["external"] = true;
+						} else {
+							$this->dump[$file_name]["categories"][$current_category]["external"] = false;
+						}
+						
+						$this->current_class = &$this->dump[$category_owner]["classes"][$current_class];
+						
+						// insert into headers category array
+						$this->dump[$file_name]["categories"][$current_category]["name"] = $current_category;
+						$this->dump[$file_name]["categories"][$current_category]["super"] = $current_class;
+						$this->dump[$file_name]["categories"][$current_category]["comment"] = $this->InsertCurrentComment();
+						$this->dump[$file_name]["categories"][$current_category]["external_name"] = $category_name;
+	
+						// append to master list of categories
+						$this->dump["categories"][$category_name][] = $current_class;
+						
+					}
+				}
+			}
+			
+		//print_r($this->current_class);
+	}
+	
+	// Parse all "pre-defined" category methods in a header
+	function PreparseCategoryMethods ($file) {
+			$contents = ReadTextFile($file);
+			$file_name = substr($file, (strripos($file, "/")) + 1, strlen($file));
+			
+			$lines = explode("\n", $contents);
+			foreach ($lines as $line) {
+							
+				// skip blocks
+				if ($this->SkipBlock($line)) continue;
+
+				// parse category
+				if ($got_category) {
+					
+					// build method fragment
+					if ($method_fragment) $method_fragment .= " ".trim($line, " 	");
+					
+					// found method fragment termination
+					if (($method_fragment) && (eregi($this->regex_objc_method_terminate, $line))) {
+						$line = $method_fragment;
+						$method_fragment = null;
+					}
+					
+					// found method
+					$method = null;
+					if (eregi($this->regex_objc_method_params, $line, $captures)) {
+						$method = $this->ConvertObjcMethodToPascal($current_category, $line, $captures, array(), true, "");						
+					} elseif (eregi($this->regex_objc_method_no_params, $line, $captures)) {
+						$method = $this->ConvertObjcMethodToPascal($current_category, $line, $captures, array(), false, "");	
+					} elseif (eregi($this->regex_objc_method_partial, $line, $captures)) {
+						$method_fragment = $line;
+					}
+					
+					// append to classes
+					if (($method) && ($current_class)) {
+						$this->dump[$category_owner]["category_methods"][] = $method["name"];
+						//print($method["name"]."\n");
+					}
+					
+					// found the end
+					if (ereg("^@end", $line)) $got_category = false;
+				}
+				
+				// got category
+				if (eregi($this->regex_objc_category, $line, $captures)) {
+					$category_owner = $this->FindCategoryHeader($captures[1]);
+					if ($category_owner) {
+						$got_category = true;
+						$current_category = $captures[2];
+						$current_class = $captures[1];
+					} else {
+						$current_class = null;
+					}
+				}
+			}
+			
+		return $this->dump[$category_owner]["category_methods"];
+	}
+	
+	// Preparses a class for protected keywords
+	function PreparseClass ($lines, $line_count) {
+		$protected_keywords = array();
+		
+		for ($i=$line_count; $i < count($lines); $i++) { 
+			$line = $lines[$i - 1];
+			
+			// skip blocks
+			if ($this->SkipBlock($line)) continue;
+
+			// build method fragment
+			if ($method_fragment) $method_fragment .= " ".trim($line, " 	");
+			
+			// found method fragment termination
+			if (($method_fragment) && (eregi($this->regex_objc_method_terminate, $line))) {
+				$line = $method_fragment;
+				$method_fragment = null;
+			}
+			
+			// found method
+			if (eregi($this->regex_objc_method_params, $line, $captures)) {
+				$method = $this->ConvertObjcMethodToPascal($current, $line, $captures, $protected_keywords, true, "");
+				$this->current_class["protected_keywords"][] = strtolower($method["name"]);
+			} elseif (eregi($this->regex_objc_method_no_params, $line, $captures)) {
+				$method = $this->ConvertObjcMethodToPascal($current, $line, $captures, $protected_keywords, false, "");
+				$this->current_class["protected_keywords"][] = strtolower($method["name"]);
+			} elseif (eregi($this->regex_objc_method_partial, $line, $captures)) {
+				$method_fragment = $line;
+			}
+			
+			// class ended
+			if (ereg("^@end", $line)) return $protected_keywords;
+		}
+	}
+	
+	// Gets the preferred property name from attributes
+	function GetPropertyName ($kind, $params, &$name) {
+		foreach ($params as $value) {
+			$pair = explode("=", $value);
+			
+			if ($pair[0] == $kind) {
+				$name = $pair[1];
+				return true;
+				break;
+			}
+		}
+	}
+
+	function EncodePointerModifiers($type, $pointertype) {
+		if ($pointertype[0] == "*") $type = $this->ReplacePointerType($type);
+		if ($pointertype[1] == "*") {
+			if ($type == "Pointer") {
+				$type = "PPointer";
+			} elseif ($type == "PChar") {
+				$type = "PPChar";
+			} elseif (in_array($type, $this->cocoa_classes)) {
+				$type = $type.$this->class_pointer_suffix;
+			} else {
+				// to match MacOSAll types
+				$type = $type."Ptr";
+			}
+		}
+		return $type;
+	}
+
+	
+	// Convert a method return type to Pascal
+	function ConvertReturnType ($type, $pointertype) {
+		$type = $this->ReplaceGarbageCollectorHints($type, $null);
+		$type = $this->ReplaceRemoteMessagingModifiers($type, $null);
+
+		// format the return type to make sure it's clean
+		$type = $this->FormatObjcType($type, $null_modifier);
+		// translate type to Pascal
+		$type = $this->ReplaceObjcType($type);
+		// incorportate pointer modifiers
+		$type = $this->EncodePointerModifiers($type,$pointertype);
+
+		return $type;
+	}
+	
+	// Checks if a line has a property and returns the parts
+	function LineHasProperty ($line, &$parts) {
+		if (eregi($this->regex_objc_property_attributes, $line, $captures)) {
+			$parts = $captures;
+			//print_r($parts);
+			return true;
+		} elseif (eregi($this->regex_objc_property, $line, $captures)) {
+			$parts = $captures;
+			//print_r($parts);
+			return true;
+		}
+	}
+	
+	// Parse a property into accessor methods
+	function ParseClassProperty ($class, $parts, $deprecatedmods) {
+		
+		$method = array();
+		//print_r($parts);
+
+		// property has attributes
+		if (count($parts) == 5) {
+			$property["parameters"] = explode(",", $parts[1]);
+			$attributes = $parts[1];
+			$type = $parts[2];
+			$pointertype = $parts[3];
+			$content = $parts[4];
+		} else {
+			$property["parameters"] = array();
+			$type = $parts[1];
+			$pointertype = $parts[2];
+			$content = $parts[3];
+		}
+		
+		// unspecified type -> id
+		if ($type == "") $type = "id";
+		
+		// get property list
+		$list = explode(",", $content);
+		if (count($list) > 1) {
+			$property_list = array();
+			foreach ($list as $key) {
+				// clean the name and remove the return type
+				$property_list[] = trim($key);
+			}
+			//print_r($property_list);
+		} else {
+			$property_list = array($content);
+		}
+		
+		$methods = array();
+		
+		foreach ($property_list as $property_name) {
+			
+			// property name
+			if (eregi("([a-zA-Z0-9_]+)[[:space:]]*$", $property_name, $captures)) $property["name"] = ucwords($captures[1]);
+
+			// property type
+			$type = $this->ConvertReturnType($type,$pointertype);
+
+			// prepare for appending
+			if ($deprecatedmods != "") $deprecatedmods .= ";";
+
+			// setter
+			if (!in_array("readonly", $property["parameters"])) {
+				$method["setter"] = array();
+
+				$name = $property["name"];
+				if (!$this->GetPropertyName("setter", $property["parameters"], $name)) {
+					$name = "set$name";
+				}
+
+				// protect method name from keywords
+				if ($this->IsKeywordReserved($name)) $name .= "_";
+
+				$method["setter"]["def"] = "procedure $name (newValue: $type);";
+				$method["setter"]["objc_method"] = "$name:";
+				$method["setter"]["class"] = $class;
+				$method["setter"]["name"] = $name;
+				$method["setter"]["kind"] = "procedure";
+				$method["setter"]["deprecated"]=$deprecatedmods;
+				//$method["setter"]["comment"] = $this->InsertCurrentComment();
+			}
+
+			// getter
+			$method["getter"] = array();
+
+			$name = $property["name"];
+			if (!$this->GetPropertyName("getter", $property["parameters"], $name)) {
+				$name = strtolower(substr($name, 0, 1)) . substr($name, 1);
+			}
+
+			// protect method name from keywords
+			if ($this->IsKeywordReserved($name)) $name .= "_";
+
+			$method["getter"]["def"] = "function $name: $type;";
+			$method["getter"]["objc_method"] = $name;
+			$method["getter"]["class"] = $class;
+			$method["getter"]["name"] = $name;
+			$method["getter"]["kind"] = "function";
+			$method["getter"]["deprecated"]=$deprecatedmods;
+			//$method["getter"]["comment"] = $this->InsertCurrentComment();
+			
+			// append to array of methods
+			$methods[] = $method;
+			
+		}
+		
+		//print_r($methods);
+		return $methods;
+	}
+	
+	// Main entry to parse a header
+	function ParseHeaderClasses ($file) {
+			$contents = ReadTextFile($file);
+			
+			$file_name = substr($file, (strripos($file, "/")) + 1, strlen($file));
+			$line_count = 0;
+			
+			// reset comments from previous parsing sections
+			$this->ResetComment();
+			
+			$lines = explode("\n", $contents);
+			foreach ($lines as $line) {
+				$line_count++;
+				
+				// skip blocks
+				if ($this->SkipBlock($line)) continue;
+						
+				// ignore lines
+				if (in_array($line, $this->ignore_lines)) continue;
+						
+				// remove macros	
+				$line = $this->RemoveVersionMacros($line, $deprecatedmods);
+												
+				// remove external class macros
+				$line = eregi_replace("^[A-Z0-9]+_EXTERN_CLASS[[:space:]]+", "", $line);
+				
+				// build comments
+				if (!$got_class) $this->BuildComment($line, $file_name);
+				
+				// parse instance vars
+				if ($got_instance_vars) {
+					
+					// scope compiler directive
+					if (eregi($this->regex_scope_compiler_directive, $line, $captures)) {
+						$this->instance_var_scope = $captures[1];
+						continue;
+					}
+					
+					// remove comments
+					$line = $this->RemoveComments($line);
+					
+					// parse instance variables
+					$result = $this->ParseInstanceVariables($line, $struct, $this->GetProtectedKeywords($this->current_class),$this->dump["master"][$this->current_class["name"]]["field_names"]);
+					
+					// parse structures
+					if ($struct["isfinished"]) {
+						//print_r($struct);
+						//$this->dump[$file_name]["classes"][$current]["ivars"][] = $struct["name"].": $current"."_".$struct["name"].";";
+						$this->dump[$file_name]["classes"][$current]["ivars_structs"][] = $struct;
+						
+						// print inline-record type
+						if ($struct["bitpacked"]) {
+							$this->dump[$file_name]["classes"][$current]["ivars"][] = $struct["name"].": ".$this->bitpacked_record_keyword;
+							$this->dump[$file_name]["classes"][$current]["ivars"][] = $this->BitPackedForceAlignment($struct["bitpacked_first_type"], "  ", "       ");
+						} else {
+							$this->dump[$file_name]["classes"][$current]["ivars"][] = $struct["name"].": ".$this->record_keyword;
+						}
+						
+						
+						// print fields
+						if ($struct["fields"]) {
+							foreach ($struct["fields"] as $field) $this->dump[$file_name]["classes"][$current]["ivars"][] = "    ".$field;
+						}
+						if ($struct["bitpacked"]) $this->dump[$file_name]["classes"][$current]["ivars"][] = "  );";
+						$this->dump[$file_name]["classes"][$current]["ivars"][] = "  end;";
+						
+						$struct = null;
+					}
+
+					if(($result != null) && ($result != "struct")) {
+						//print($result);
+						
+						// add a single string or an array of fields to the ivars array
+						if (count($result) <= 1) {
+							$this->dump[$file_name]["classes"][$current]["ivars"][] = $result;
+						} else {
+							foreach ($result as $field) {
+								$this->dump[$file_name]["classes"][$current]["ivars"][] = $field;
+							}
+						}
+					}
+					
+					// instance var section terminated.
+					if (eregi("^\s*}\s*[;]*$", $line)) {
+						$struct = null;
+						$got_instance_vars = false;
+						$this->instance_var_scope = null;
+					}
+					
+				} elseif ($got_class) { // parse the class
+					
+					// the instance variable section started after the class line and no other ivar's were parsed yet
+					if (!$this->dump[$file_name]["classes"][$current]["ivars"]) {
+						if (eregi("{\s*$", $line)) {
+							$got_instance_vars = true;
+							continue;
+						}
+					}
+					
+					// build comments
+					$this->BuildComment($line, $file_name);
+					
+					// remove comments
+					$line = $this->RemoveComments($line);
+					
+					// found property
+					if ($this->LineHasProperty($line, $captures)) {
+							$properties = $this->ParseClassProperty($current, $captures, $deprecatedmods);
+							foreach ($properties as $property) {
+								if ($property["setter"]) {
+									if ($this->AddMethodToClass($property["setter"], $this->dump[$file_name]["classes"][$current])) {
+										$this->dump[$file_name]["classes"][$current]["methods"][] = $property["setter"];
+									}
+								}
+
+								if ($property["getter"]) {
+									if ($this->AddMethodToClass($property["getter"], $this->dump[$file_name]["classes"][$current])) {
+										$this->dump[$file_name]["classes"][$current]["methods"][] = $property["getter"];
+									}
+								}
+							}
+							
+							continue;
+					}
+					
+					// build method fragment
+					if ($method_fragment) $method_fragment .= " ".trim($line, " 	");
+					
+					// found method fragment termination
+					if (($method_fragment) && (eregi($this->regex_objc_method_terminate, $line))) {
+						$line = $method_fragment;
+						$method_fragment = null;
+					}
+					
+					// found method
+					if (eregi($this->regex_objc_method_params, $line, $captures)) {
+						$method = $this->ConvertObjcMethodToPascal($current, $line, $captures, $this->GetProtectedKeywords($this->current_class), true, $deprecatedmods);						
+						if ($this->AddMethodToClass($method, $this->dump[$file_name]["classes"][$current])) {
+							//if ($this->comment_terminated) $method["comment"] = $this->InsertCurrentComment();
+							$this->dump[$file_name]["classes"][$current]["methods"][] = $method;
+						}
+						
+					} elseif (eregi($this->regex_objc_method_no_params, $line, $captures)) {
+						$method = $this->ConvertObjcMethodToPascal($current, $line, $captures, $this->GetProtectedKeywords($this->current_class), false, $deprecatedmods);
+						if ($this->AddMethodToClass($method, $this->dump[$file_name]["classes"][$current])) {
+							//if ($this->comment_terminated) $method["comment"] = $this->InsertCurrentComment();
+							$this->dump[$file_name]["classes"][$current]["methods"][] = $method;
+						}
+					} elseif (eregi($this->regex_objc_method_partial, $line, $captures)) {
+						$method_fragment = $line;
+					}
+									
+					// found the end
+					if (ereg("^@end", $line)) {
+						$got_class = false;
+						$this->ResetComment();
+					}
+				}
+
+				// ==== got class ====
+				if ((eregi($this->regex_objc_class, $line, $captures)) || (eregi($this->regex_objc_class_no_super, $line, $captures))) {
+					$current = $captures[1];
+					$got_class = true;
+					
+					// check for instance variable section
+					if (eregi("{\s*$", $line)) $got_instance_vars = true;
+					
+					// get the protocols which the class adopts
+					if (eregi($this->regex_objc_class, $line, $captures)) {
+						if ($captures[3]) $this->dump[$file_name]["classes"][$current]["adopts"] = $captures[3];
+					} else {
+						if ($captures[2]) $this->dump[$file_name]["classes"][$current]["adopts"] = $captures[2];
+					}
+					
+					// clean up the conforms string
+					if ($this->dump[$file_name]["classes"][$current]["adopts"]) {
+						$conform_protocols = explode(",", $this->dump[$file_name]["classes"][$current]["adopts"]);
+						$protocol_list = array();
+						
+						foreach ($conform_protocols as $protocol) {
+							$protocol = trim($protocol, "<> ");
+							$protocol_clean .= $protocol."$this->protocol_suffix, ";
+							$protocol_list[] = $protocol;
+						}
+						
+						$protocol_clean = trim($protocol_clean, ", ");
+						$this->dump[$file_name]["classes"][$current]["adopts"] = $protocol_clean;
+						$this->dump[$file_name]["classes"][$current]["protocols"] = $protocol_list;
+
+						$protocol_clean = "";
+					}
+					
+					$this->dump[$file_name]["classes"][$current]["name"] = $captures[1];
+					$this->dump[$file_name]["classes"][$current]["super"] = $captures[2];
+					$this->dump[$file_name]["classes"][$current]["super_class"] = &$this->dump["master"][$captures[2]];
+					$this->dump[$file_name]["classes"][$current]["file_name"] = $file_name;
+					$this->dump[$file_name]["classes"][$current]["file_clean"] = substr($file_name, 0, (strripos($file_name, ".")));
+					$this->dump[$file_name]["classes"][$current]["protected_keywords"] = array();
+					$this->dump[$file_name]["classes"][$current]["declared_methods"] = array();
+					$this->dump[$file_name]["classes"][$current]["comment"] = $this->InsertCurrentComment();
+					
+					$this->dump[$file_name]["category_methods"] = array();
+					
+					$this->current_class = &$this->dump[$file_name]["classes"][$current];
+					
+					// append master class listing
+					$this->dump["master"][$current] = &$this->dump[$file_name]["classes"][$current];
+					
+					// preparse for protected keywords
+					$this->PreparseClass($lines, $line_count);
+					
+					// preparse for category methods that may present naming conflicts
+					$category_methods = $this->PreparseCategoryMethods($file);
+					
+					// add category methods to protected keywords
+					if ($category_methods) $this->current_class["protected_keywords"] = array_merge($this->current_class["protected_keywords"], $category_methods);
+					
+					// print class hierarchy
+					if ($this->show_class_hierarchy) {
+						$this->GetClassHierarchy($this->current_class, $hierarchy);
+						$hierarchy_string = "";
+						foreach ($hierarchy as $value) {
+							$hierarchy_string .= "$value->";
+						}
+						$hierarchy_string = trim($hierarchy_string, "->");
+						print("	- $current: $hierarchy_string\n");
+					}
+					
+					$this->class_count ++;
+					//print_r($this->dump[$file_name]["classes"][$current]);
+				}
+				
+			}
+		
+		//print_r($this->dump[$file_name]["classes"][$current]);
+	}		
+	
+	// Parse categories which depend on another header
+	function ParseHeaderDependents ($file) {
+		$file_name = substr($file, (strripos($file, "/")) + 1, strlen($file));
+
+		$this->ParseHeaderCategories($file);
+			
+		print("+ Parsed $file_name for dependents\n");
+	}
+	
+	
+	// Main entry to parse a header
+	function ParseHeader ($file) {
+			$file_name = substr($file, (strripos($file, "/")) + 1, strlen($file));
+			$name_clean = substr($file_name, 0, (strripos($file_name, ".")));	
+			
+			// get the framework we're parsing from if it was specified during a batch parse
+			if ((!$this->framework) && (eregi("/([a-zA-Z]+)\.framework", $file, $captures))) $this->framework = strtolower($captures[1]);
+			
+			// get the output path
+			$this->dump[$file_name]["path"] = "$this->root$this->out/$this->framework/$name_clean.inc";
+			$this->dump[$file_name]["path_partial"] = "$this->framework/$name_clean.inc";
+			$this->dump[$file_name]["path_merge"] = $this->dump[$file_name]["path"].".merge";
+			$this->dump[$file_name]["framework"] = $this->framework;
+			$this->dump[$file_name]["name"] = $file_name;
+			$this->dump[$file_name]["name_clean"] = $name_clean;
+			$this->dump[$file_name]["anoninternstrucs"] = 0;
+			$this->dump[$file_name]["anonbitfields"] = 0;
+			$this->current_header = &$this->dump[$file_name];
+			$this->ParseHeaderTypes($file);
+			$this->ParseHeaderProtocols($file);
+			$this->ParseHeaderClasses($file);
+			
+			print("+ Parsed $file_name\n");
+	}
+			
+	// Parse all AppKit and Foundation framework headers
+	function ParseAllFrameworks ($ignore_files, $parse_only) {
+		
+		foreach ($this->frameworks as $framework_name => $framework_info) {
+			
+			// framework is disabled
+			if ($framework_info["enabled"] != 1) continue;
+			
+			// set the current framework being parsed
+			$this->framework = $framework_name;
+
+			if ($this->out != "/") {
+				$path = $this->root.$this->out."/".$framework_info["root"];
+			} else {
+				$path = $this->root.$framework_info["root"];
+			}
+			
+			// Load the header if found
+			if (file_exists($path)) {
+				$contents = ReadTextFile($path);
+				$lines = explode("\n", $contents);
+
+				foreach ($lines as $line) {
+					
+					$header = null;
+					$path = null;
+
+					// parse the header path from the {$include} macro
+					if (eregi($framework_info["include_pattern"], $line, $captures)) {
+						$header = $captures[1].".h";
+						$path = $framework_info["headers"]."/$header";
+					}
+
+					// parse the header path from {-parse} directive
+					if (eregi("^\{-parse[[:space:]]+(.*)[[:space:]]*\}", $line, $captures)) {
+						$header = $captures[1];
+						$path = $framework_info["headers"]."/$header";
+					}
+					
+					// parse the header if valid
+					if (file_exists($path)) {
+						
+						// main header
+						if ($parse_only) {
+							if (@in_array($header, $parse_only)) $this->ParseHeader($path);
+						} elseif (@!in_array($header, $ignore_files)) {
+							$this->ParseHeader($path);
+						}
+
+						// header dependents
+						if ($parse_only) {
+							if (@in_array($header, $parse_only)) $this->ParseHeaderDependents($path);
+						} elseif (@!in_array($header, $ignore_files)) {
+							 $this->ParseHeaderDependents($path);
+						}
+						
+					} elseif ($header) {
+						print("*** The header $path could not be found. ***\n");
+						$this->warning_count++;
+					}
+				}
+			} else {
+				print("*** The master include ".$framework_info["root"]." is missing. ***\n");
+				exit;
+			}	
+		}
+		
+		// diagnostics
+		print("\n• Parsed $this->method_count methods in $this->class_count classes.\n\n");
+		
+		if ($this->warning_count > 0) print("• $this->warning_count warnings were encountered.\n\n");
+	}
+						
+	// Parse all classes/categories (non-delegate) from the header
+	function CollectHeaderClasses ($file) {
+		
+		// can't find the header, bail
+		if (!file_exists($file)) return;
+			
+		$contents = ReadTextFile($file);
+			
+		$lines = explode("\n", $contents);
+		foreach ($lines as $line) {
+			
+			// remove external class macros
+			$line = eregi_replace("^[A-Z0-9]+_EXTERN_CLASS[[:space:]]+", "", $line);
+			
+			// classes
+			if (eregi($this->regex_objc_class, $line, $captures)) {
+				$this->defined_cocoa_classes[] = $captures[1];
+				// may already have been parsed as an anonymous class
+				if (!in_array($captures[1], $this->cocoa_classes))
+				  $this->cocoa_classes[] = $captures[1];
+			}
+			if (eregi($this->regex_objc_class_no_super, $line, $captures)) {
+				$this->defined_cocoa_classes[] = $captures[1];
+				// may already have been parsed as an anonymous class
+				if (!in_array($captures[1], $this->cocoa_classes))
+				  $this->cocoa_classes[] = $captures[1];
+			}
+			// anonymous classes ===
+			if (eregi($this->regex_objc_anon_class, $line, $captures)) {
+				$anon_classes = explode(",", $captures[1]);
+				foreach ($anon_classes as $anon_class) {
+					$anon_class=trim($anon_class);
+					// may already have been parsed as a regular class
+					if (!in_array($anon_class, $this->cocoa_classes)) {
+						$this->cocoa_classes[] = $anon_class;
+						if (!in_array($anon_class, $this->anon_cocoa_classes)) {
+							$this->anon_cocoa_classes[] = $anon_class;
+						}
+					}
+				}
+			}
+				
+			// categories
+			if (eregi($this->regex_objc_category, $line, $captures)) {
+				$this->cocoa_categories[] = $captures[1];
+			}
+		}
+	}
+		
+	// Build array of all known classes in frameworks	
+	function BuildFrameworkClasses () {
+	
+		foreach ($this->frameworks as $framework_name => $framework_info) {
+			
+			// framework is disabled
+			if ($framework_info["enabled"] != 1) continue;
+			$handle = opendir($framework_info["headers"]);
+			while (($file = readdir($handle)) !== false) {
+				if (eregi($framework_info["header_pattern"], $file)) {
+					$this->CollectHeaderClasses($framework_info["headers"]."/$file");
+				}
+			}
+			closedir($handle);
+		}
+	}		
+
+	function ProcessFile ($file, $print) {
+		
+		// set the current framework to null so it's parsed from the framework
+		$this->framework = null;
+		
+		$this->ParseHeader($file);
+		$this->ParseHeaderDependents($file);
+
+		if ($print) $this->PrintAllHeaders("", null, null, false);
+	}
+	
+	function LoadFrameworksXML ($framework_path) {
+		$xml = new SimpleXMLElement(file_get_contents("frameworks.xml"));
+		
+		foreach ($xml as $framework) {
+				$this->frameworks[(string) $framework->name]["root"] = (string) $framework->root;
+				$this->frameworks[(string) $framework->name]["bridge"] = (string) $framework->bridge;
+				$this->frameworks[(string) $framework->name]["headers"] = (string) $framework->headers;
+				if ($framework_path != "")
+					$this->frameworks[(string) $framework->name]["headers"] = preg_replace("!^.*/System/Library/Frameworks!", $framework_path, $this->frameworks[(string) $framework->name]["headers"]);
+				$this->frameworks[(string) $framework->name]["include_pattern"] = (string) $framework->include_pattern;
+				$this->frameworks[(string) $framework->name]["header_pattern"] = (string) $framework->header_pattern;
+				$this->frameworks[(string) $framework->name]["external_macro"] = (string) $framework->external_macro;
+				$this->frameworks[(string) $framework->name]["ignore_types"] = (string) $framework->ignore_types;
+				$this->frameworks[(string) $framework->name]["ignore_methods"] = (string) $framework->ignore_methods;
+				$this->frameworks[(string) $framework->name]["replace_types"] = $framework->replace_types;
+				$this->frameworks[(string) $framework->name]["ignore_lines"] = $framework->ignore_lines;
+				$this->frameworks[(string) $framework->name]["ignore_comments"] = $framework->ignore_comments;
+				$this->frameworks[(string) $framework->name]["enabled"] = false;
+				$this->frameworks[(string) $framework->name]["print"] = true;
+		}
+		
+	}
+		
+	function __construct ($directory, $out_directory, $frameworks, $frameworks_path, $show)  {
+		$this->root = $directory;
+		$this->out = $out_directory;
+		$this->show = $show;
+		
+		// load defined frameworks from xml
+		$this->LoadFrameworksXML($frameworks_path);
+		
+		// enable frameworks requested by the command line options
+		if ($frameworks) {
+			foreach ($frameworks as $name) {
+				$name_clean = trim($name, "^ ");
+				$this->frameworks[$name_clean]["enabled"] = true;
+				
+				// apply options from framework definition
+				if ($this->frameworks[$name_clean]["external_macro"]) $this->external_string_macros .= "|".$this->frameworks[$name_clean]["external_macro"];
+				
+				if ($this->frameworks[$name_clean]["ignore_types"]) $this->ignore_types = array_merge($this->ignore_types, explode(",", $this->frameworks[$name_clean]["ignore_types"]));
+				if ($this->frameworks[$name_clean]["ignore_methods"]) $this->ignore_methods = array_merge($this->ignore_methods, explode(",", $this->frameworks[$name_clean]["ignore_methods"]));
+
+				if ($this->frameworks[$name_clean]["ignore_lines"]) {
+					foreach ($this->frameworks[$name_clean]["ignore_lines"]->line as $line) {
+						if (!in_array($line, $this->ignore_lines)) $this->ignore_lines[] = (string)$line;
+					}
+				}
+
+				if ($this->frameworks[$name_clean]["ignore_comments"]) {
+					foreach ($this->frameworks[$name_clean]["ignore_comments"]->line as $line) {
+						if (!in_array($line, $this->ignore_comments)) $this->ignore_comments[] = (string)$line;
+					}
+				}
+
+				if ($this->frameworks[$name_clean]["replace_types"]) {
+					foreach ($this->frameworks[$name_clean]["replace_types"]->type as $type) {
+						$pair = explode("=", (string)$type);
+						$this->replace_types[$pair[0]] = $pair[1];
+					}
+				}
+				
+				// print mode
+				if ($name[0] == "^") $this->frameworks[$name_clean]["print"] = false;
+			}
+		}
+		
+		//print_r($this->ignore_comments);
+		//print_r($this->ignore_lines);
+		//print_r($this->frameworks);
+		//exit;
+		$this->BuildFrameworkClasses();
+	}
+}
+?>

+ 4 - 0
packages/cocoaint/utils/uikit-skel/src/InlineFunctions.inc

@@ -0,0 +1,4 @@
+function NSSTR (inString: PChar): NSString;
+begin
+  Result := NSString(CFSTR(inString));
+end;

+ 69 - 0
packages/cocoaint/utils/uikit-skel/src/UndefinedTypes.inc

@@ -0,0 +1,69 @@
+type
+  __NSAppleEventManagerSuspension = record end;
+  IBAction = Pointer;
+  objc_protocol = protocol;
+  idptr = ^id;
+  idptrptr = ^idptr;
+  SELptr = ^SEL;
+
+{ Variable argument list - disabled for Pascal }
+type
+ va_list_rec = record
+ end;
+ va_list = ^va_list_rec;
+
+{ Private instance variable types }
+type
+ _NSImageCellAnimationState = Pointer;
+ _CGLPBufferObject = Pointer;
+ PATHSEGMENT = Pointer;		{from NSBezierPath.h what is this???}
+ 
+{ from CoreData }
+type
+ NSAttributeType = NSUInteger;
+
+{ Pointer C-Types }
+
+{ An array of objects }
+type
+  NSObjectArrayOfObjects = array[0..(high(longint) div sizeof(id))-1] of id;
+  NSObjectArrayOfObjectsPtr = ^NSObjectArrayOfObjects;
+
+{ Cocoa types }
+const
+ UINT_MAX = high(culong);
+// 7.18.2.4 Limits of integer types capable of holding object pointers
+ INTPTR_MIN = low(ptrint);
+ INTPTR_MAX = high(ptrint);
+ UINTPTR_MAX = high(ptruint);
+// 7.18.2.5 Limits of greatest-width integer types
+ INTMAX_MIN = low(int64);
+ INTMAX_MAX = high(int64);
+ UINTMAX_MAX = high(qword);
+// 7.18.3 "Other"
+ PTRDIFF_MIN = INTPTR_MIN;
+ PTRDIFF_MAX = INTPTR_MAX;
+
+{ from IOKit (not yet part of univint) }
+const
+ NX_TABLET_POINTER_UNKNOWN = 0;
+ NX_TABLET_POINTER_PEN = 1;
+ NX_TABLET_POINTER_CURSOR = 2;
+ NX_TABLET_POINTER_ERASER = 3;
+ 
+ NX_SUBTYPE_DEFAULT = 0;
+ NX_SUBTYPE_TABLET_POINT = 1;
+ NX_SUBTYPE_TABLET_PROXIMITY = 2;
+ NX_SUBTYPE_MOUSE_TOUCH = 3;
+ 
+ NX_TABLET_BUTTON_PENTIPMASK = $0001;
+ NX_TABLET_BUTTON_PENLOWERSIDEMASK = $0002;
+ NX_TABLET_BUTTON_PENUPPERSIDEMASK = $0004;
+  
+{ Parser hacks - these types should never exist }
+type
+  __NSAppleEventManagerSuspensionPtr = Pointer;
+
+  { does not really exist, is in inactive part of ifdef }
+  NSURLHandleClientProtocol = objcprotocol
+  end; external;

+ 79 - 0
packages/cocoaint/utils/uikit-skel/src/foundation/Foundation.inc

@@ -0,0 +1,79 @@
+{ include Foundation.inc}
+
+{$include NSObjCRuntime.inc}
+{$include NSValue.inc}
+{$include NSString.inc}
+{$include NSArray.inc}
+{$include NSSet.inc}
+{$include NSPredicate.inc}
+{$include NSFormatter.inc}
+{$include NSScanner.inc}
+
+{$include FoundationErrors.inc}
+{$include NSAttributedString.inc}
+{$include NSAutoreleasePool.inc}
+{$include NSBundle.inc}
+{$include NSByteOrder.inc}
+{$include NSCalendar.inc}
+{$include NSCharacterSet.inc}
+{$include NSCoder.inc}
+{$include NSComparisonPredicate.inc}
+{$include NSCompoundPredicate.inc}
+{$include NSData.inc}
+{$include NSDate.inc}
+{$include NSDateFormatter.inc}
+{$include NSDecimal.inc}
+{$include NSDecimalNumber.inc}
+{$include NSDictionary.inc}
+{$include NSEnumerator.inc}
+{$include NSError.inc}
+{$include NSException.inc}
+{$include NSExpression.inc}
+{$include NSFileHandle.inc}
+{$include NSFileManager.inc}
+{$include NSHTTPCookie.inc}
+{$include NSHTTPCookieStorage.inc}
+{$include NSIndexPath.inc}
+{$include NSIndexSet.inc}
+{$include NSInvocation.inc}
+{$include NSKeyValueCoding.inc}
+{$include NSKeyValueObserving.inc}
+{$include NSKeyedArchiver.inc}
+{$include NSLocale.inc}
+{$include NSLock.inc}
+{$include NSMethodSignature.inc}
+{$include NSNetServices.inc}
+{$include NSNotification.inc}
+{$include NSNotificationQueue.inc}
+{$include NSNull.inc}
+{$include NSNumberFormatter.inc}
+{$include NSObject.inc}
+{$include NSOperation.inc}
+{$include NSPathUtilities.inc}
+{$include NSPort.inc}
+{$include NSProcessInfo.inc}
+{$include NSPropertyList.inc}
+{include NSProxy.inc}
+{$include NSRange.inc}
+{$include NSRunLoop.inc}
+{$include NSSortDescriptor.inc}
+{$include NSStream.inc}
+{$include NSThread.inc}
+{$include NSTimeZone.inc}
+{$include NSTimer.inc}
+{$include NSURL.inc}
+{$include NSURLAuthenticationChallenge.inc}
+{$include NSURLCache.inc}
+{$include NSURLConnection.inc}
+{$include NSURLCredential.inc}
+{$include NSURLCredentialStorage.inc}
+{$include NSURLError.inc}
+{$include NSURLProtectionSpace.inc}
+{$include NSURLProtocol.inc}
+{$include NSURLRequest.inc}
+{$include NSURLResponse.inc}
+{$include NSUndoManager.inc}
+{$include NSUserDefaults.inc}
+{$include NSValueTransformer.inc}
+{$include NSXMLParser.inc}
+{$include NSZone.inc}

+ 106 - 0
packages/cocoaint/utils/uikit-skel/src/iPhoneAll.pas

@@ -0,0 +1,106 @@
+unit iPhoneAll;
+
+{$mode delphi}
+{$modeswitch objectivec1}
+{$modeswitch cvar}
+
+interface
+
+{$linkframework CoreFoundation}
+{$linkframework CoreGraphics}
+{$linkframework UIKit}
+
+uses
+  ctypes,
+  CFBase,CFArray,CFBag,CFCharacterSet,CFData,CFDate,CFDictionary,CFNumber,CFPropertyList,CFSet,CFString,CFStringEncodingExt,CFTimeZone,CFTree,CFURL,CFXMLNode,CFXMLParser,CFMachPort,CFMessagePort,CFRunLoop,CFSocket,CFBinaryHeap,CFBitVector,CFBundle,CFByteOrders,CFPlugIn,CFPreferences,CFURLAccess,CFUUID,CFLocale,CFStream,CFDateFormatter,CFNumberFormatter,CFCalendar,CFUserNotification,CFNotificationCenter,CFAttributedString,CFNetworkErrorss,
+  CGBase,CGAffineTransforms,CGBitmapContext,CGColor,CGColorSpace,CGContext,CGDataConsumer,CGDataProvider,CGDirectDisplay,CGDirectPalette,CGDisplayConfiguration,CGDisplayFades,CGErrors,CGEvent,CGEventSource,CGEventTypes,CGFont,CGFunction,CGGLContext,CGGeometry,CGImage,CGLayer,CGPDFArray,CGPDFContentStream,CGPDFContext,CGPDFDictionary,CGPDFDocument,CGPDFObject,CGPDFOperatorTable,CGPDFPage,CGPDFScanner,CGPDFStream,CGPDFString,CGPSConverter,CGPath,CGPattern,CGRemoteOperation,CGSession,CGShading,CGWindowLevels,
+  MacTypes, AEDataModel, Icons, SecBase, SecTrust,
+  AnonClassDefinitionsUikit;
+  
+{$define INTERFACE}
+
+{$include UndefinedTypes.inc}
+{$include uikit/AnonIncludeClassDefinitionsUikit.inc}
+
+{$define HEADER}
+{$include foundation/Foundation.inc}
+{$include opengles/OpenGLES.inc}
+{$include quartzcore/QuartzCore.inc}
+{$include uikit/UIKit.inc}
+{$undef HEADER}
+
+{$define TYPES}
+{$include foundation/Foundation.inc}
+{$include opengles/OpenGLES.inc}
+{$include quartzcore/QuartzCore.inc}
+{$include uikit/UIKit.inc}
+{$undef TYPES}
+
+{$define RECORDS}
+{$include foundation/Foundation.inc}
+{$include opengles/OpenGLES.inc}
+{$include quartzcore/QuartzCore.inc}
+{$include uikit/UIKit.inc}
+{$undef RECORDS}
+
+type
+{$define FORWARD}
+{$include foundation/Foundation.inc}
+{$include opengles/OpenGLES.inc}
+{$include quartzcore/QuartzCore.inc}
+{$include uikit/UIKit.inc}
+{$undef FORWARD}
+
+{$define PROTOCOLS}
+{$include foundation/Foundation.inc}
+{$include opengles/OpenGLES.inc}
+{$include quartzcore/QuartzCore.inc}
+{$include uikit/UIKit.inc}
+{$undef PROTOCOLS}
+
+{$define CLASSES}
+{$include foundation/Foundation.inc}
+{$include opengles/OpenGLES.inc}
+{$include quartzcore/QuartzCore.inc}
+{$include uikit/UIKit.inc}
+{$undef CLASSES}
+ 
+{$define FUNCTIONS}
+{$include foundation/Foundation.inc}
+{$include opengles/OpenGLES.inc}
+{$include quartzcore/QuartzCore.inc}
+{$include uikit/UIKit.inc}
+{$undef FUNCTIONS}
+
+{$define EXTERNAL_SYMBOLS}
+{$include foundation/Foundation.inc}
+{$include opengles/OpenGLES.inc}
+{$include quartzcore/QuartzCore.inc}
+{$include uikit/UIKit.inc}
+{$undef EXTERNAL_SYMBOLS}
+
+{$define USER_PATCHES}
+{$include foundation/Foundation.inc}
+{$include opengles/OpenGLES.inc}
+{$include quartzcore/QuartzCore.inc}
+{$include uikit/UIKit.inc}
+{$undef USER_PATCHES}
+
+{ Inline functions }
+function NSSTR (inString: PChar): NSString;
+
+{$undef INTERFACE}
+implementation
+{$define IMPLEMENTATION}
+
+{$include InlineFunctions.inc}
+
+{$define USER_PATCHES}
+{$include foundation/Foundation.inc}
+{$include opengles/OpenGLES.inc}
+{$include quartzcore/QuartzCore.inc}
+{$include uikit/UIKit.inc}
+{$undef USER_PATCHES}
+
+{$undef IMPLEMENTATION}
+end.

+ 3 - 0
packages/cocoaint/utils/uikit-skel/src/opengles/OpenGLES.inc

@@ -0,0 +1,3 @@
+{$include EAGL.inc}
+{$include EAGLDrawable.inc}
+

+ 19 - 0
packages/cocoaint/utils/uikit-skel/src/quartzcore/QuartzCore.inc

@@ -0,0 +1,19 @@
+{$include CAAnimation.inc}
+{$include CABase.inc}
+{$include CADisplayLink.inc}
+{$include CALayer.inc}
+{$include CAEAGLLayer.inc}
+{$include CAGradientLayer.inc}
+{$include CAMediaTiming.inc}
+{$include CAMediaTimingFunction.inc}
+{$include CAReplicatorLayer.inc}
+{$include CAScrollLayer.inc}
+{$include CAShapeLayer.inc}
+{$include CATextLayer.inc}
+{$include CATiledLayer.inc}
+{$include CATransaction.inc}
+{$include CATransform3D.inc}
+{$include CATransformLayer.inc}
+{$include CAValueFunction.inc}
+{ include CoreAnimation.inc}
+{ include QuartzCore.inc}

+ 76 - 0
packages/cocoaint/utils/uikit-skel/src/uikit/UIKit.inc

@@ -0,0 +1,76 @@
+{$include UIResponder.inc}
+{$include UIView.inc}
+{$include UIControl.inc}
+{$include UIViewController.inc}
+{$include UINavigationController.inc}
+
+{$include UIAccelerometer.inc}
+{$include UIAccessibility.inc}
+{$include UIAccessibilityConstants.inc}
+{$include UIAccessibilityElement.inc}
+{$include UIActivityIndicatorView.inc}
+{$include UIBarItem.inc}
+{$include UIBarButtonItem.inc}
+{$include UIBezierPath.inc}
+{$include UIButton.inc}
+{$include UIColor.inc}
+{$include UIDataDetectors.inc}
+{$include UIDatePicker.inc}
+{$include UIDevice.inc}
+{$include UIApplication.inc}
+{$include UIDocumentInteractionController.inc}
+{$include UIEvent.inc}
+{$include UIFont.inc}
+{$include UIGeometry.inc}
+{$include UIGestureRecognizer.inc}
+{$include UIGestureRecognizerSubclass.inc}
+{$include UIGraphics.inc}
+{$include UIImage.inc}
+{$include UIImagePickerController.inc}
+{$include UIImageView.inc}
+{$include UIInterface.inc}
+{$include UIAlert.inc}
+{$include UIKitDefines.inc}
+{$include UILabel.inc}
+{$include UILocalizedIndexedCollation.inc}
+{$include UILongPressGestureRecognizer.inc}
+{$include UIMenuController.inc}
+{$include UINavigationBar.inc}
+{$include UINibDeclarations.inc}
+{$include UINibLoading.inc}
+{$include UIPageControl.inc}
+{$include UIPanGestureRecognizer.inc}
+{$include UIPasteboard.inc}
+{$include UIPickerView.inc}
+{$include UIPinchGestureRecognizer.inc}
+{$include UIPopoverController.inc}
+{$include UIProgressView.inc}
+{$include UIRotationGestureRecognizer.inc}
+{$include UIScreen.inc}
+{$include UIScreenMode.inc}
+{$include UIScrollView.inc}
+{$include UISearchBar.inc}
+{$include UISearchDisplayController.inc}
+{$include UISegmentedControl.inc}
+{$include UISlider.inc}
+{$include UISplitViewController.inc}
+{$include UIStringDrawing.inc}
+{$include UISwipeGestureRecognizer.inc}
+{$include UISwitch.inc}
+{$include UITabBar.inc}
+{$include UITabBarController.inc}
+{$include UITabBarItem.inc}
+{$include UITableView.inc}
+{$include UITableViewCell.inc}
+{$include UITableViewController.inc}
+{$include UITapGestureRecognizer.inc}
+{$include UITextChecker.inc}
+{$include UITextField.inc}
+{$include UITextInput.inc}
+{$include UITextInputTraits.inc}
+{$include UITextView.inc}
+{$include UIToolbar.inc}
+{$include UITouch.inc}
+{$include UIVideoEditorController.inc}
+{$include UIWebView.inc}
+{$include UIWindow.inc}