[22706] users

source_changes at macosforge.org source_changes at macosforge.org
Mon Mar 12 01:51:33 PDT 2007


Revision: 22706
          http://trac.macosforge.org/projects/macports/changeset/22706
Author:   rhwood at macports.org
Date:     2007-03-12 01:51:09 -0700 (Mon, 12 Mar 2007)

Log Message:
-----------
Add directory for self and experimental Aqua GUI for MacPorts

Added Paths:
-----------
    users/rhwood/
    users/rhwood/Pallet/
    users/rhwood/Pallet/ApplicationIcon.icns
    users/rhwood/Pallet/ApplicationIconBusy.icns
    users/rhwood/Pallet/AuthorizedExecutable.h
    users/rhwood/Pallet/AuthorizedExecutable.m
    users/rhwood/Pallet/Debug.h
    users/rhwood/Pallet/English.lproj/
    users/rhwood/Pallet/English.lproj/InfoPlist.strings
    users/rhwood/Pallet/English.lproj/MainMenu.nib/
    users/rhwood/Pallet/English.lproj/MainMenu.nib/classes.nib
    users/rhwood/Pallet/English.lproj/MainMenu.nib/info.nib
    users/rhwood/Pallet/English.lproj/MainMenu.nib/keyedobjects.nib
    users/rhwood/Pallet/Halt.tiff
    users/rhwood/Pallet/Info.plist
    users/rhwood/Pallet/Install.tiff
    users/rhwood/Pallet/Launcher copy.h
    users/rhwood/Pallet/Launcher.c
    users/rhwood/Pallet/Launcher.h
    users/rhwood/Pallet/Launcher.m
    users/rhwood/Pallet/Launcher_Prefix.pch
    users/rhwood/Pallet/MPPort.h
    users/rhwood/Pallet/MPPort.m
    users/rhwood/Pallet/MPPortsController.h
    users/rhwood/Pallet/MPPortsController.m
    users/rhwood/Pallet/MPToolbar.h
    users/rhwood/Pallet/MPToolbar.m
    users/rhwood/Pallet/PAStatusTransformer.h
    users/rhwood/Pallet/PAStatusTransformer.m
    users/rhwood/Pallet/Pallet.pmproj
    users/rhwood/Pallet/Pallet.xcodeproj/
    users/rhwood/Pallet/Pallet.xcodeproj/project.pbxproj
    users/rhwood/Pallet/Pallet.xcodeproj/rhwood.mode1
    users/rhwood/Pallet/Pallet.xcodeproj/rhwood.pbxuser
    users/rhwood/Pallet/Port Authority_Prefix.pch
    users/rhwood/Pallet/PortAuthority.h
    users/rhwood/Pallet/PortAuthority.m
    users/rhwood/Pallet/Remove.tiff
    users/rhwood/Pallet/Sync.tiff
    users/rhwood/Pallet/TaskWrapper.h
    users/rhwood/Pallet/TaskWrapper.m
    users/rhwood/Pallet/Update.tiff
    users/rhwood/Pallet/Upgrade.tiff
    users/rhwood/Pallet/UserDefaults.plist
    users/rhwood/Pallet/active.gif
    users/rhwood/Pallet/getpath.c
    users/rhwood/Pallet/installed.gif
    users/rhwood/Pallet/main.m
    users/rhwood/Pallet/outdated.gif

Added: users/rhwood/Pallet/ApplicationIcon.icns
===================================================================
(Binary files differ)


Property changes on: users/rhwood/Pallet/ApplicationIcon.icns
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: users/rhwood/Pallet/ApplicationIconBusy.icns
===================================================================
(Binary files differ)


Property changes on: users/rhwood/Pallet/ApplicationIconBusy.icns
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: users/rhwood/Pallet/AuthorizedExecutable.h
===================================================================
--- users/rhwood/Pallet/AuthorizedExecutable.h	                        (rev 0)
+++ users/rhwood/Pallet/AuthorizedExecutable.h	2007-03-12 08:51:09 UTC (rev 22706)
@@ -0,0 +1,110 @@
+/*
+ File: AuthorizedExecutable.h
+
+ FinkCommander
+
+ Graphical user interface for Fink, a software package management system
+ that automates the downloading, patching, compilation and installation of
+ Unix software on Mac OS X.
+
+ AuthorizedExecutable uses an NSTask to run the Launcher tool with administrative
+ privileges.  It communicates with Launcher, and thus with fink or apt-get subprocesses,
+ through pipes and sends the output from the subprocesses to FinkController through 
+ delegate methods.
+
+ Created by David Love on Thu Jul 18 2002.
+ Copyright (c) 2002 Cashmere Software, Inc.
+ Released to Steven J. Burr on August 21, 2002, under the Gnu General Public License.
+ 
+ A few minor modifications to Dave's orginal code have been made.
+
+ This program is free software; you may redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+ Contact the author at sburrious at users.sourceforge.net.
+
+*/
+
+#import <Foundation/Foundation.h>
+#import <Security/Authorization.h>
+
+ at interface AuthorizedExecutable : NSObject {
+
+    AuthorizationRef authorizationRef;
+    NSMutableArray* arguments;
+	NSDictionary* environment;
+    NSString* authExecutable;
+    id delegate;
+    bool mustBeAuthorized;
+    NSMutableString* output;
+    NSFileHandle *stdinHandle;
+    NSFileHandle *stdoutHandle;
+    NSFileHandle *stderrHandle;
+    NSTask *task;
+}
+
+-(id)initWithExecutable:(NSString*)exe;
+
+-(void)dealloc;
+
+-(bool)authorize;
+-(bool)authorizeWithQuery;
+-(bool)checkAuthorizationWithFlags:(AuthorizationFlags) flags;
+
+-(bool)isAuthorized;
+-(bool)mustBeAuthorized;
+-(void)setMustBeAuthorized:(bool)b;
+-(void)unAuthorize;
+
+-(NSString*)authExecutable;
+-(void)setAuthExecutable:(NSString*)exe;
+-(bool)isExecutable;
+-(NSDictionary *)environment;
+-(void)setEnvironment:(NSDictionary *)env;
+- (NSMutableArray*)arguments;
+-(void)setArguments:(NSMutableArray*)args;
+
+-(void)captureStdOut:(NSNotification*)notification;
+-(void)captureStdErr:(NSNotification*)notification;
+- (bool)isRunning;
+- (void)log:(NSString*)str;
+- (void)logStdOut:(NSString*)str;
+- (void)logStdErr:(NSString*)str;
+- (void)writeData:(NSData*)data;
+- (void)writeToStdin:(NSString*)str;
+- (void)start;
+- (void)stop;
+
+- (id)delegate;
+- (void)setDelegate:(id)dgate;
+
+// Delegates available:
+//
+// (void)captureOutput:(NSString*)str forExecutable:(AuthorizedExecutable*)exe;
+//      - captured whenever data is available on stdout or stderr
+//      - the stdout and stderr delegates (below) take precendence over this
+//        routine and will effectively filter out any applicable messages.
+//        If you provide delegates from both captureStdOut and captureStdErr,
+//        this routine will only be called when the log method is directly
+//        called by your application.
+//
+// (void)captureStdOut:(NSString*)str forExecutable:(AuthorizedExecutable*)exe;
+//      - called whenever data is available on stdout
+//
+// (void)captureStdErr:(NSString*)str forExecutable:(AuthorizedExecutable*)exe;
+//      - called whenever data is available on stderr
+//
+// (void)executableFinished:(AuthorizedExecutable*)exe withStatus:(int)status;
+//      - called when the executable exits
+ at end

Added: users/rhwood/Pallet/AuthorizedExecutable.m
===================================================================
--- users/rhwood/Pallet/AuthorizedExecutable.m	                        (rev 0)
+++ users/rhwood/Pallet/AuthorizedExecutable.m	2007-03-12 08:51:09 UTC (rev 22706)
@@ -0,0 +1,500 @@
+/*
+ File: AuthorizedExecutable.m
+
+ Created by David Love on Thu Jul 18 2002.
+ Copyright (c) 2002 Cashmere Software, Inc.
+ Released to Steven J. Burr on August 21, 2002, under the Gnu General Public License.
+
+ See the header file, AuthorizedExecutable.h for more information on the license.
+
+*/
+
+#import <Security/AuthorizationTags.h>
+#import "AuthorizedExecutable.h"
+
+ at implementation AuthorizedExecutable
+
+// This needs to be initialized with the full path to the Launcher
+// executable (which should be setuid root).  Note that this is
+// different from the executable you want eventually run.  That
+// executable will be specified as the first entry in the arguments
+// array.
+//
+- (id)initWithExecutable:(NSString*)exe
+{
+    if (self = [super init])
+    {
+        NSMutableArray* args = [[NSMutableArray alloc] init];
+        [self setArguments:args];
+        [args release];
+		NSDictionary *env = [[NSDictionary alloc] init];
+		[self setEnvironment:env];
+		[env release];
+        output = [[NSMutableString alloc] init];
+        [output retain];
+        [self setAuthExecutable:exe];
+        [self setMustBeAuthorized:false];
+    }
+    return self;
+}
+
+
+// self-explanatory
+//
+-(void)dealloc
+{
+    [self stop];
+    [self setAuthExecutable:nil];
+    [self setArguments:nil];
+	[self setEnvironment:nil];
+    [output release];
+	[super dealloc];
+}
+
+
+// The command and arguments you want to run.  This is passed
+// directly to NSTask.  The first entry is the command you want
+// to run.  Any other entries are the options you want passed 
+// to the command.  Note that if an option has an associated
+// argument (-r foo), they must be specified in the array as
+// *two* entries ('-r' and 'foo'), not one.
+//
+-(NSMutableArray*)arguments
+{
+    return arguments;
+}
+
+-(void)setArguments:(NSMutableArray*)args
+{
+    [args retain];
+    [arguments release];
+    arguments = args;
+}
+
+-(NSDictionary *)environment
+{
+	return environment;
+}
+
+-(void)setEnvironment:(NSDictionary *)env
+{
+	[env retain];
+	[environment release];
+	environment = env;
+}
+
+
+// Helper routine.  Both authorize and authorizedWithQuery call
+// this routine to check the authorization.  They just use different
+// flags to determine if the 'authorization dialog' should be 
+// displayed.
+//
+-(bool)checkAuthorizationWithFlags:(AuthorizationFlags)flags
+{
+    AuthorizationRights rights;
+    AuthorizationItem items[1];
+    OSStatus err = errAuthorizationSuccess;
+
+    if (! [self isExecutable])
+    {
+        return false;
+    }
+
+    if (authorizationRef == NULL)
+    {
+        err = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment,
+                                  kAuthorizationFlagDefaults, &authorizationRef);
+     }
+
+    if (err == errAuthorizationSuccess)
+    {
+        // There should be one item in the AuthorizationItems array for each
+        // right you want to acquire.
+        // The data in the value and valueLength is dependent on which right you
+        // want to acquire.
+        // For the right to execute tools as root, kAuthorizationRightExecute,
+        // they should hold a pointer to a C string containing the path to
+        // the tool you want to execute, and the length of the C string path.
+        // There needs to be one item for each tool you want to execute.
+		items[0].name = "org.macports.portauthority";
+		items[0].value = 0;
+		items[0].valueLength = 0;		
+        items[0].flags = 0;
+        rights.count=1;
+        rights.items = items;
+        // Since we've specified kAuthorizationFlagExtendRights and
+        // haven't specified kAuthorizationFlagInteractionAllowed, if the
+        // user isn't currently authorized to execute tools as root,
+        // they won't be asked for a password and err will indicate
+        // an authorization failure.
+        err = AuthorizationCopyRights(authorizationRef,&rights,
+                                      kAuthorizationEmptyEnvironment,
+                                      flags, NULL);
+    }
+	NSLog(@"Authorization Success: %@", [NSNumber numberWithInt:err]);
+    return errAuthorizationSuccess==err;
+}
+
+
+// attempt to authorize the user without displaying the authorization dialog.
+//
+-(bool)authorize
+{
+    return [self checkAuthorizationWithFlags:kAuthorizationFlagExtendRights];
+}
+
+
+// attempt to authorize the user, displaying the authorization dialog
+// if necessary.
+//
+-(bool)authorizeWithQuery
+{
+    return [self checkAuthorizationWithFlags:kAuthorizationFlagExtendRights| kAuthorizationFlagInteractionAllowed];
+}
+
+// accessor for the Launcher program
+//
+- (NSString*)authExecutable
+{
+    return authExecutable;
+}
+
+// Helper routine which converts the current authorizionRef to its 
+// external form.  The external form will eventually get piped
+// to the Launcher.
+//
+-(bool)fillExternalAuthorizationForm:(AuthorizationExternalForm*)extAuth
+{
+    bool result = false;
+    if (authorizationRef)
+    {
+        result = errAuthorizationSuccess != AuthorizationMakeExternalForm(authorizationRef, extAuth);
+    }
+    return result;
+}
+
+// self-explanatory
+//
+-(bool)isAuthorized
+{
+    return [self authorize];
+}
+
+// Determine if the Launcher exists and is executable.
+//
+-(bool)isExecutable
+{
+    NSString* exe = [self authExecutable];
+    return exe != nil && [[NSFileManager defaultManager] isExecutableFileAtPath:exe];
+}
+
+-(bool)mustBeAuthorized
+{
+    return mustBeAuthorized;
+}
+
+
+// Call this with 'true' if the user must be authorized before
+// running the command.  The default value for this is false
+//
+-(void)setMustBeAuthorized:(bool)b
+{
+    mustBeAuthorized = b;
+}
+
+// deprecated (just instantiate a new AuthorizedExecutable object if you
+// want a different launcher).
+//
+-(void)setAuthExecutable:(NSString*)exe
+{
+    [self unAuthorize];
+    [exe retain];
+    [authExecutable release];
+    authExecutable = exe;
+}
+
+// Free any existing authorization.  This sets the user to an unauthorized
+// state.
+//
+-(void)unAuthorize
+{
+    if (authorizationRef != NULL)
+    {
+        AuthorizationFree(authorizationRef,kAuthorizationFlagDestroyRights);
+        authorizationRef = NULL;
+    }
+}
+
+-(void)setDelegate:(id)dgate
+{
+    [dgate retain];
+    [delegate release];
+    delegate = dgate;
+}
+
+-(id)delegate
+{
+    return delegate;
+}
+
+
+// This saves the output of the command in the output string.  A
+// delegate should implement captureOutput:forExecutable to receive
+// the command's output
+-(void)log:(NSString*)str
+{
+    if ([[self delegate] respondsToSelector:@selector(captureOutput:forExecutable:)])
+    {
+        [[self delegate] performSelector:@selector(captureOutput:forExecutable:) 
+						 withObject:str withObject:self];
+    }
+    else
+    {
+        [output replaceCharactersInRange:NSMakeRange([output length], 0) 
+				withString:str];
+    }
+}
+
+// This saves capture the program's stdout and either passes it to a delegate, if assigned,
+// or to the log method.
+//
+-(void)logStdOut:(NSString*)str
+{
+    if ([[self delegate] respondsToSelector:@selector(captureStdOut:forExecutable:)])
+    {
+        [[self delegate] performSelector:@selector(captureStdOut:forExecutable:) 
+							withObject:str 
+							withObject:self];
+    }
+    else
+    {
+        [self log:str];
+    }
+}
+
+// This saves capture the program's stderr and either passes it to a delegate, if assigned,
+// or to the log method.
+//
+-(void)logStdErr:(NSString*)str
+{
+    if ([[self delegate] respondsToSelector:@selector(captureStdErr:forExecutable:)])
+    {
+        [[self delegate] performSelector:@selector(captureStdErr:forExecutable:) 
+							withObject:str 
+							withObject:self];
+    }
+    else
+    {
+        [self log:str];
+    }
+}
+
+-(void)writeData:(NSData*)data
+{
+    if ([self isRunning])
+    {
+        [stdinHandle writeData:data];
+    }
+}
+
+-(void)writeToStdin:(NSString*)str
+{
+    [self writeData:[str dataUsingEncoding:NSASCIIStringEncoding]];
+}
+
+// Internal routines used to capture output asynchronously.
+// If a delegate overrides the executableFinished:withStatus method,
+// it will be called when the command exits.
+//
+//  (void)executableFinished:(AuthorizedExecutable*)exe withStatus:(int)status;
+//
+
+//Helper method
+-(NSString *)stringFromOutputData:(NSData *)data
+{
+	NSString *outputString;
+	
+	NS_DURING
+		outputString = [NSString stringWithCString:[data bytes] length:[data length]];
+		return outputString;	
+	NS_HANDLER
+		return @"WARNING:  Unable to decode output for display.\n";
+	NS_ENDHANDLER
+	;
+}
+
+-(void)captureStdOut:(NSNotification*)notification
+{
+    NSData *inData = [[notification userInfo] objectForKey:NSFileHandleNotificationDataItem];
+    if (inData == nil || [inData length] == 0)
+    {
+        [task waitUntilExit];
+        [self stop];
+    }
+    else
+    {
+        [self logStdOut:[NSString stringWithCString:[inData bytes] 
+			    length:[inData length]]];
+        [stdoutHandle readInBackgroundAndNotify];
+    }
+}
+
+// Internal routine used to capture stderr asynchronously.
+//
+-(void)captureStdErr:(NSNotification*)notification
+{
+    NSData *inData = [[notification userInfo] objectForKey:NSFileHandleNotificationDataItem];
+    if (inData != nil && [inData length] != 0)
+    {
+        [self logStdErr:[NSString stringWithCString:[inData bytes]
+                                             length:[inData length]]];
+        [stderrHandle readInBackgroundAndNotify];
+    }
+}
+
+// task status
+//
+- (bool)isRunning
+{
+    return [task isRunning];
+}
+
+
+// Call this to start the command.  If the command is already running,
+// this is a no-op.
+- (void)start
+{
+    if (! [task isRunning])
+    {
+        AuthorizationExternalForm extAuth;
+        OSStatus err;
+        NSPipe *stdinPipe = nil;
+        NSPipe *stdoutPipe = nil;
+        //NSPipe *stderrPipe = nil;
+
+        [output setString:@""];
+
+        if (! [self isExecutable])
+        {
+            [self log:
+                NSLocalizedString(@"I can't find the tool I use to run an authorized command. You'll need to reinstall this application\n",@"This warning is issued if the user tries to start this task and the Launcher can't be found or isn't executable")];
+			return;
+        }
+
+		if ([self mustBeAuthorized] && ! [self isAuthorized])
+		{
+			[self log:
+				NSLocalizedString(@"You must authorize yourself before you can run this command.\n",@"This warning is issued if the user tries to start this task when the mustBeAuthorized flag is set and the user isn't authorized")];
+			return;
+		}
+        err = AuthorizationMakeExternalForm(authorizationRef, &extAuth);
+        if (err != errAuthorizationSuccess)
+        {
+            [self log:[NSString stringWithFormat:@"TODO: Unknown error in AuthorizationMakeExternalForm: (%d)\n", err]];
+            return;
+        }
+
+        NS_DURING
+            stdoutPipe = [NSPipe pipe];
+            stdinPipe = [NSPipe pipe];
+            //stderrPipe = [NSPipe pipe];
+
+            stdinHandle = [stdinPipe fileHandleForWriting];
+            [stdinHandle retain];
+            stdoutHandle = [stdoutPipe fileHandleForReading];
+            [stdoutHandle retain];
+            //stderrHandle = [stderrPipe fileHandleForReading];
+            //[stderrHandle retain];
+
+            [[NSNotificationCenter defaultCenter] 
+						addObserver:self 
+						selector:@selector(captureStdOut:)
+						name:NSFileHandleReadCompletionNotification
+						object:stdoutHandle];
+#ifdef UNDEF
+            [[NSNotificationCenter defaultCenter] 
+						addObserver:self selector:@selector(captureStdErr:)
+						name:NSFileHandleReadCompletionNotification
+						object:stderrHandle];
+#endif
+            [stdoutHandle readInBackgroundAndNotify];
+            //[stderrHandle readInBackgroundAndNotify];
+
+            task = [[NSTask alloc] init];
+            [task retain];
+            [task setStandardOutput:stdoutPipe];
+            [task setStandardInput:stdinPipe];
+			//my change:
+			[task setStandardError:stdoutPipe];
+            //[task setStandardError:stderrPipe];
+
+            [task setLaunchPath:[self authExecutable]];
+			NSLog(@"Launching %@", [self authExecutable]);
+            [task setArguments:[self arguments]];
+			NSLog(@"Setting arguments");
+			[task setEnvironment:[self environment]];
+			NSLog(@"Setting environment");
+            [task launch];
+			NSLog(@"Launched Launcher");
+            [self writeData:[NSData dataWithBytes:&extAuth 
+				  length:sizeof(AuthorizationExternalForm)]];
+
+        NS_HANDLER
+            [self log:[NSString stringWithFormat:@"Failed while trying to launch helper program"]];
+            [self stop];
+        NS_ENDHANDLER
+        ;
+    }
+}
+
+// This terminates the running process, if necessary, and cleans up 
+// any related objects.
+//
+- (void)stop
+{
+	int status;
+
+    if (stdoutHandle)
+    {
+        [[NSNotificationCenter defaultCenter] 
+			removeObserver:self
+			name:NSFileHandleReadCompletionNotification
+			object:stdoutHandle];
+    }
+    if (stderrHandle)
+    {
+        [[NSNotificationCenter defaultCenter] 
+			removeObserver:self
+			name:NSFileHandleReadCompletionNotification
+			object:stderrHandle];
+    }
+    if ([task isRunning])
+    {
+		NSLog(@"Task terminated");
+        [task terminate];
+		[task waitUntilExit];
+    }
+	status = [task terminationStatus];
+    [task release];
+	[stdinHandle closeFile];
+	[stdoutHandle closeFile];
+	//[stderrHandle closeFile];
+    [stdinHandle release];
+    [stdoutHandle release];
+    //[stderrHandle release];
+    task = nil;
+    stdoutHandle = nil;
+    stdinHandle = nil;
+    //stderrHandle = nil;
+	if ([[self delegate]
+				respondsToSelector:@selector(executableFinished:withStatus:)])
+	{
+		[[self delegate]
+				performSelector:@selector(executableFinished:withStatus:)
+					 withObject:self
+					 withObject:[NSNumber numberWithInt:status]];
+	}	
+}
+
+
+ at end

Added: users/rhwood/Pallet/Debug.h
===================================================================
--- users/rhwood/Pallet/Debug.h	                        (rev 0)
+++ users/rhwood/Pallet/Debug.h	2007-03-12 08:51:09 UTC (rev 22706)
@@ -0,0 +1,12 @@
+/*
+ *  Debug.h
+ *  Pallet
+ *
+ *  Created by Randall Hansen Wood on 11/3/2007.
+ *  Copyright 2007 Randall Wood and the Macports Project. All rights reserved.
+ *
+ */
+
+#ifndef DEBUG
+	#define DEBUG 1
+#endif
\ No newline at end of file

Added: users/rhwood/Pallet/English.lproj/InfoPlist.strings
===================================================================
(Binary files differ)


Property changes on: users/rhwood/Pallet/English.lproj/InfoPlist.strings
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: users/rhwood/Pallet/English.lproj/MainMenu.nib/classes.nib
===================================================================
--- users/rhwood/Pallet/English.lproj/MainMenu.nib/classes.nib	                        (rev 0)
+++ users/rhwood/Pallet/English.lproj/MainMenu.nib/classes.nib	2007-03-12 08:51:09 UTC (rev 22706)
@@ -0,0 +1,81 @@
+{
+    IBClasses = (
+        {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, 
+        {
+            ACTIONS = {
+                about = id; 
+                haltPortCommand = id; 
+                installPort = id; 
+                macPortsSite = id; 
+                portAuthoritySite = id; 
+                reinstallPort = id; 
+                removePort = id; 
+                syncPortsList = id; 
+                updateMacPorts = id; 
+                upgradeOutdated = id; 
+                upgradePort = id; 
+            }; 
+            CLASS = MPAuthority; 
+            LANGUAGE = ObjC; 
+            OUTLETS = {
+                portIndexController = MPPortsController; 
+                portInfo = NSTextView; 
+                portLog = NSTextView; 
+                portLogWindow = NSWindow; 
+                portsList = NSTableView; 
+                portsWindow = NSWindow; 
+                progressIndicator = NSProgressIndicator; 
+                status = NSTextField; 
+            }; 
+            SUPERCLASS = NSObject; 
+        }, 
+        {CLASS = MPPort; LANGUAGE = ObjC; SUPERCLASS = NSMutableDictionary; }, 
+        {
+            ACTIONS = {search = id; }; 
+            CLASS = MPPortsController; 
+            LANGUAGE = ObjC; 
+            SUPERCLASS = NSArrayController; 
+        }, 
+        {
+            ACTIONS = {search = id; }; 
+            CLASS = MPToolbar; 
+            LANGUAGE = ObjC; 
+            OUTLETS = {
+                portAuthority = MPAuthority; 
+                ports = NSWindow; 
+                searchField = NSSearchField; 
+                searchView = NSView; 
+            }; 
+            SUPERCLASS = NSObject; 
+        }, 
+        {
+            ACTIONS = {
+                about = id; 
+                haltPortCommand = id; 
+                installPort = id; 
+                macPortsSite = id; 
+                portAuthoritySite = id; 
+                reinstallPort = id; 
+                removePort = id; 
+                syncPortsList = id; 
+                updateMacPorts = id; 
+                upgradeOutdated = id; 
+                upgradePort = id; 
+            }; 
+            CLASS = PortAuthority; 
+            LANGUAGE = ObjC; 
+            OUTLETS = {
+                portIndexController = MPPortsController; 
+                portInfo = NSTextView; 
+                portLog = NSTextView; 
+                portLogWindow = NSWindow; 
+                portsList = NSTableView; 
+                portsWindow = NSWindow; 
+                progressIndicator = NSProgressIndicator; 
+                status = NSTextField; 
+            }; 
+            SUPERCLASS = NSObject; 
+        }
+    ); 
+    IBVersion = 1; 
+}
\ No newline at end of file

Added: users/rhwood/Pallet/English.lproj/MainMenu.nib/info.nib
===================================================================
--- users/rhwood/Pallet/English.lproj/MainMenu.nib/info.nib	                        (rev 0)
+++ users/rhwood/Pallet/English.lproj/MainMenu.nib/info.nib	2007-03-12 08:51:09 UTC (rev 22706)
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>IBDocumentLocation</key>
+	<string>82 22 356 240 0 0 1280 832 </string>
+	<key>IBEditorPositions</key>
+	<dict>
+		<key>29</key>
+		<string>201 458 366 44 0 0 1280 832 </string>
+		<key>290</key>
+		<string>555 518 170 75 0 0 1280 832 </string>
+		<key>292</key>
+		<string>82 267 75 68 0 0 1280 832 </string>
+	</dict>
+	<key>IBFramework Version</key>
+	<string>446.1</string>
+	<key>IBLockedTabItems</key>
+	<array>
+		<integer>210</integer>
+	</array>
+	<key>IBOpenObjects</key>
+	<array>
+		<integer>21</integer>
+		<integer>290</integer>
+	</array>
+	<key>IBSystem Version</key>
+	<string>8L127</string>
+</dict>
+</plist>

Added: users/rhwood/Pallet/English.lproj/MainMenu.nib/keyedobjects.nib
===================================================================
(Binary files differ)


Property changes on: users/rhwood/Pallet/English.lproj/MainMenu.nib/keyedobjects.nib
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: users/rhwood/Pallet/Halt.tiff
===================================================================
(Binary files differ)


Property changes on: users/rhwood/Pallet/Halt.tiff
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: users/rhwood/Pallet/Info.plist
===================================================================
--- users/rhwood/Pallet/Info.plist	                        (rev 0)
+++ users/rhwood/Pallet/Info.plist	2007-03-12 08:51:09 UTC (rev 22706)
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>Pallet</string>
+	<key>CFBundleIconFile</key>
+	<string>ApplicationIcon</string>
+	<key>CFBundleIdentifier</key>
+	<string>org.MacPorts.Pallet</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>${PRODUCT_NAME}</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>Pallet 0.1.0</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>1</string>
+	<key>NSHumanReadableCopyright</key>
+	<string>© The MacPorts Project, 2006, 2007</string>
+	<key>NSMainNibFile</key>
+	<string>MainMenu</string>
+	<key>NSPrincipalClass</key>
+	<string>NSApplication</string>
+</dict>
+</plist>

Added: users/rhwood/Pallet/Install.tiff
===================================================================
(Binary files differ)


Property changes on: users/rhwood/Pallet/Install.tiff
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: users/rhwood/Pallet/Launcher copy.h
===================================================================
--- users/rhwood/Pallet/Launcher copy.h	                        (rev 0)
+++ users/rhwood/Pallet/Launcher copy.h	2007-03-12 08:51:09 UTC (rev 22706)
@@ -0,0 +1,16 @@
+//
+//  Launcher.h
+//  Port Authority
+//
+//  Created by Randall Hansen Wood on 27/12/2006.
+//  Copyright 2006 __MyCompanyName__. All rights reserved.
+//
+
+#include <Foundation/Foundation.h>
+#include <Security/Authorization.h>
+
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "TaskWrapper.h"
+

Added: users/rhwood/Pallet/Launcher.c
===================================================================
--- users/rhwood/Pallet/Launcher.c	                        (rev 0)
+++ users/rhwood/Pallet/Launcher.c	2007-03-12 08:51:09 UTC (rev 22706)
@@ -0,0 +1,395 @@
+/*
+ File: Launcher.c
+
+ Created by David Love on Thu Jul 18 2002.
+ Copyright (c) 2002 Cashmere Software, Inc.
+ Released to Steven J. Burr on August 21, 2002, under the Gnu General Public License.
+
+ See the header file, Launcher.h for more information on the license.
+
+ */
+
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <sys/errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <mach-o/dyld.h>
+#include <Security/Authorization.h>
+
+#include "Launcher.h"
+
+#define BUFSIZE 4096
+
+static AuthorizationExternalForm extAuth;
+
+enum {
+    cmdAuthorized,
+    cmdNotAuthorized,
+    cmdStatusUndetermined,
+    cmdNotOwnedByRoot
+};
+
+/*
+* Read the incoming authorization byte blob and make sure it's valid
+ */
+bool readAuthorization(AuthorizationRef *auth)
+{
+    bool result = FALSE;
+
+    if (read(0, &extAuth, sizeof(extAuth)) == sizeof(extAuth))
+    {
+        int err;
+        err = AuthorizationCreateFromExternalForm(&extAuth, auth);
+        result = err == errAuthorizationSuccess;
+    }
+    fflush(stdout);
+    return result;
+}
+
+bool authorizedToExecute(AuthorizationRef *auth, const char* cmd)
+{
+    AuthorizationItem right = { "org.macports.portauthority", 0, NULL, 0 };
+    AuthorizationRights rights = { 1, &right };
+    AuthorizationFlags flags =
+        kAuthorizationFlagDefaults | kAuthorizationFlagExtendRights;
+    bool result = getuid() == geteuid();
+
+    if(! result)
+    {
+        result = AuthorizationCopyRights(*auth, &rights,
+                                         kAuthorizationEmptyEnvironment,
+                                         flags, NULL) == errAuthorizationSuccess;
+    }
+    return result;
+}
+
+
+/*
+ * Determine if the command is one we really want to run as root
+ */
+int isauthorizedcmd(char * const *cmd, int args)
+{
+    struct stat st;
+
+    /* Test program name */
+    if (!strstr(cmd[1], "/bin/port")		&&
+		!strstr(cmd[1], "/bin/portindex")		&&
+		!strstr(cmd[1], "/bin/portmirror")){
+		return cmdNotAuthorized;
+    }
+    /* Make sure program is owned by root, so it could not have been installed or
+		replaced by an ordinary user */
+    if (stat(cmd[1], &st) != 0) return cmdStatusUndetermined;
+    if (st.st_uid != 0) return cmdNotOwnedByRoot;
+    return cmdAuthorized;
+}
+
+
+/*
+ * Perform an authorized command
+ */
+int perform(const char* cmd, char * const *argv)
+{
+    int status;
+    int result = 1;
+    int pid;
+
+    pid = fork();
+    if (pid == 0) {
+		/* If this is the child process, then try to exec cmd */
+
+		setuid(geteuid()); /* set ruid = euid to avoid perl's taint mode */
+
+		if (execvp(cmd, argv) == -1){
+			fprintf(stderr, "Execution failed.  errno=%d (%s)\n", errno, strerror(errno));
+		}
+    }
+    else if (pid == -1)
+    {
+		fprintf(stderr, "fork() failed.  errno=%d (%s)\n", errno, strerror(errno));
+    }
+    else  {
+		fflush(stderr);
+		waitpid(pid,&status,0);
+		if (WIFEXITED(status))
+		{
+			result = WEXITSTATUS(status);
+		}
+		else if (WIFSIGNALED(status))
+		{
+			result = WTERMSIG(status)+32;
+		}
+    }
+    return result;
+}
+
+/*
+ *  Copy function used by write_fconf
+ */
+int mycopy(const char *fromfile, const char *tofile, bool create)
+{
+    char buffer[BUFSIZE];
+    int in_file, out_file;
+    int rsize, wsize;
+    int wflags = create ? O_WRONLY|O_TRUNC|O_CREAT : O_WRONLY|O_TRUNC;
+
+    /* 	Open fromfile for reading */
+    in_file = open(fromfile, O_RDONLY);
+    if (in_file == -1) {
+		fprintf(stderr, "Failed to open %s for reading, errno=%d (%s)\n",
+		  fromfile, errno, strerror(errno));
+		return 1;
+    }
+    /*	Open tofile for writing */
+    out_file = open(tofile, wflags, 0644);
+    if (out_file == -1) {
+		fprintf(stderr,"Failed to open %s for writing, errno=%d (%s)\n",
+		  tofile, errno, strerror(errno));
+		return 1;
+    }
+    while (1){
+		/*	Read fromfile */
+		rsize = read(in_file, buffer, sizeof(buffer));
+		if (rsize == 0){	/* EOF */
+			break;
+		}
+		if (rsize == -1){
+			fprintf(stderr,"Reading %s failed, errno=%d (%s)\n",
+				fromfile, errno, strerror(errno));
+			return 1;
+		}
+		/*	Write tofile  */
+		wsize = write(out_file, buffer, (unsigned int)rsize);
+		if (wsize == -1){
+			fprintf(stderr,"Reading %s failed, errno=%d (%s)\n",
+				tofile, errno, strerror(errno));
+			return 1;
+		}
+    }
+	close(in_file);
+	close(out_file);
+	return 0;
+}
+
+/*
+ *  Back up fink.conf to fink.conf~.
+ *  Read in fink.conf.tmp created by FinkConf writeToFile method
+ *  Write contents to fink.conf.
+ */
+int write_fconf(char *basepath)
+{
+    char fcpath[256];
+    char bkpath[256];
+    const char *tmpath = "/private/tmp/port.conf.tmp";
+    int result;
+
+    strcpy(fcpath, basepath);
+    strcpy(bkpath, basepath);
+    strcat(fcpath, "/etc/port.conf");
+    strcat(bkpath, "/etc/port.conf~");
+
+    /* Back up fink.conf to fink.conf~ */
+    result = mycopy(fcpath, bkpath, 1);
+    if (result > 0) return result;
+    /* Write new fink.conf */
+    result = mycopy(tmpath, fcpath, 0);
+    return result;
+}
+
+/*
+ * Self repair code.  We ran ourselves using
+ * AuthorizationExecuteWithPrivileges() so we need to make
+ * ourselves setuid root to avoid the need for this the next time
+ * around.
+ * In addition, we set the owner of the Resources directory to root
+ * to prevent someone without administrator privileges from replacing
+ * Launcher with a malicious version.
+ */
+int repair_self()
+{
+    AuthorizationRef auth;
+    struct stat st;
+    int fd_tool;
+    int result = FALSE;
+    int resrep = TRUE;
+	int chownerr = 0;
+	int chmoderr;
+    char* path_to_self = getPathToMyself();
+    char path_to_res[BUFSIZE];
+    char* end_of_dir;
+
+ /* Don't change ownership of Resource directory during development;
+    it causes clean build to fail. */
+#ifndef DEBUGGING
+	resrep = FALSE;
+    /* Get path to Resource directory */
+    strcpy(path_to_res, path_to_self);
+    end_of_dir = strrchr(path_to_res, '/');
+    if (end_of_dir == NULL) path_to_res[0] = 0;  /* signal failure */
+    else *end_of_dir = 0;  /* terminate string at slash */
+#endif //DEBUGGING
+
+    if (path_to_self != NULL){
+        /* Recover the passed in AuthorizationRef. */
+        if (AuthorizationCopyPrivilegedReference(&auth, kAuthorizationFlagDefaults)
+            == errAuthorizationSuccess){
+
+            /* Open tool exclusively, so no one can change it while we bless it */
+            fd_tool = open(path_to_self, O_NONBLOCK|O_RDONLY|O_EXLOCK, 0);
+            if ((fd_tool != -1) && (fstat(fd_tool, &st) == 0)){
+                if (st.st_uid != 0)
+                    chownerr = fchown(fd_tool, 0, st.st_gid);
+
+                /* Disable group and world writability and make setuid root. */
+                chmoderr = fchmod(fd_tool, (st.st_mode & (~(S_IWGRP|S_IWOTH))) | S_ISUID);
+                close(fd_tool);
+				if (0 == chownerr && 0 == chmoderr){
+					result = TRUE;
+				}
+            }
+#ifndef DEBUGGING
+			/* Set ownership of Resource directory to root and disable group and world
+				writability */
+			if (path_to_res[0] != 0){
+				if (stat(path_to_res, &st) == 0){
+					chownerr = chown(path_to_res, 0, st.st_gid);
+					chmoderr = chmod(path_to_res, st.st_mode & (~(S_IWGRP|S_IWOTH)));
+					if (0 == chownerr && 0 == chmoderr){
+						resrep = TRUE;
+					}
+				}
+			}
+#endif //DEBUGGING
+		}else{
+			fprintf(stderr, "Authentication as administrator failed.\n");
+		}
+		free(path_to_self);
+    }else{
+		fprintf(stderr, "Unable to determine path to setuid tool.\n");
+    }
+
+    if (result && resrep){
+		fprintf(stderr, "Self-repair succeeded\n");
+    }else if (result){
+		fprintf(stderr, "/n/nWARNING:  Unable to modify Resource directory\n");
+    }else{
+		fprintf(stderr, "/n/nERROR:  Self-repair failed.  Please be sure you are running Pallet from a directory and disk you are authorized to modify (e.g., not a disk image).\n");
+    }
+    return ! result;  //will be used as exit code; so return 0 if successful, 1 otherwise
+}
+
+/*
+ * This is taken almost directly from Apple's example code and will
+ * attempt to reset the launcher's setuid permissions if necessary.
+ */
+int launch_to_repair_self(AuthorizationRef* auth)
+{
+    int status;
+    FILE *commPipe = NULL;
+    char *arguments[] = { "--self-repair", NULL };
+    int result = EXIT_FAILURE;
+
+    char* path_to_self = getPathToMyself();
+    if (path_to_self != NULL){
+		fprintf(stderr, "Running self-repair");   /* signal to FinkOutputParser */
+		  /* Set our own stdin and stdout to be the communication channel
+		  with ourself. */
+		  if (AuthorizationExecuteWithPrivileges(*auth, path_to_self, kAuthorizationFlagDefaults,
+										   arguments, &commPipe) == errAuthorizationSuccess)
+		  {
+			  /* Read from stdin and write to commPipe. */
+			  fwrite(&extAuth, 1, sizeof(extAuth),commPipe);
+			  /* Flush any remaining output. */
+			  fflush(commPipe);
+
+			  /* Close the communication pipe to let the child know we are done. */
+			  fclose(commPipe);
+
+			  /* Wait for the child of AuthorizationExecuteWithPrivileges to exit. */
+			  if (wait(&status) != -1 && WIFEXITED(status))
+			  {
+				  result = WEXITSTATUS(status);
+			  }
+		  }
+		  free(path_to_self);
+    }
+
+/* Exit with the same exit code as the child spawned by
+ * AuthorizationExecuteWithPrivileges()
+ */
+return result;
+}
+
+
+int
+main(int argc, char * const *argv)
+{
+    AuthorizationRef auth;
+    int result = 1;
+
+	fprintf(stderr, "Running port...\n");
+	/* The caller *must* pass in a valid AuthorizationExternalForm structure on stdin
+	 * before they're allowed to go any further.
+	 */
+    if (! readAuthorization(&auth)){
+        fprintf(stderr, "Failed to read authorization from stdin\n");
+        exit(1);
+    }
+
+    if (argc == 2 && 0 == strcmp(argv[1], "--self-repair")){
+        result = repair_self();
+    }else if (geteuid() != 0){
+		/* If the effective uid isn't root's (0), then we need to reset
+		 * the setuid bit on the executable, if possible.
+		 */
+		result = launch_to_repair_self(&auth);
+    }else{
+        if (! authorizedToExecute(&auth, argv[1])){
+            /* If the caller isn't authorized to run as root, then reset
+			 * the effective uid before spawning command
+			 */
+            seteuid(getuid());
+        }
+		if (argc == 3 && 0 == strcmp(argv[1], "--kill")){
+			/* Kill command being run by Launcher in another process */
+			pid_t pid = (pid_t)strtol(argv[2], nil, 10);
+			fprintf(stdout, "Killing process %s", argv[2]);
+			result = killpg(pid, SIGKILL);
+		}else if (argc == 3 && 0 == strcmp(argv[1], "--write_fconf")){
+			/* Write changes to fink.conf */
+			result = write_fconf(argv[2]);
+		}else{
+			int pgid;
+			pgid = (int)getpgrp();
+			//fprintf(stderr, "PGID=%d", pgid);
+			switch (isauthorizedcmd(argv, argc)){
+				case cmdAuthorized:
+					result = perform(argv[1], &argv[1]);
+					break;
+				case cmdNotAuthorized:
+					fprintf(stderr, "WARNING:  An attempt was made to use the Launcher "
+							"tool in  Pallet to run an unauthorized command: %s\n", argv[1]);
+					break;
+				case cmdStatusUndetermined:
+					fprintf(stderr, "Error:  Pallet was unable to determine "
+							"the owner of %s.\nFor security reasons, Pallet will "
+							"not run %s unless it can determine that it is owned by root.\n",
+							argv[1], argv[1]);
+					break;
+				case cmdNotOwnedByRoot:
+					fprintf(stderr, "Error:  %s is not owned by root.\nFor security reasons, "
+							"Pallet will not run %s unless it is owned by root.\n",
+							argv[1], argv[1]);
+					break;
+			}
+		}
+    }
+    exit(result);
+}
+
+

Added: users/rhwood/Pallet/Launcher.h
===================================================================
--- users/rhwood/Pallet/Launcher.h	                        (rev 0)
+++ users/rhwood/Pallet/Launcher.h	2007-03-12 08:51:09 UTC (rev 22706)
@@ -0,0 +1,40 @@
+/*
+ File: Launcher.h
+
+ FinkCommander
+
+ Graphical user interface for Fink, a software package management system
+ that automates the downloading, patching, compilation and installation of
+ Unix software on Mac OS X.
+
+ This file, Launcher.c and getpath.c are used to build the setuid root Launcher tool which runs 
+ fink and apt-get commands, terminates those commands at the request of the user and
+ writes changes to fink.conf.
+
+ Created by David Love on Thu Jul 18 2002.
+ Copyright (c) 2002 Cashmere Software, Inc.
+ Released to Steven J. Burr on August 21, 2002, under the Gnu General Public License.
+ 
+ I've made some changes to David's code.  If you see anything in here that doesn't make sense:
+ (a) You can safely assume it's my modification, not the original code.
+ (b) Let me know.
+ 
+ This program is free software; you may redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+ Contact the author at sburrious at users.sourceforge.net.
+
+ */
+
+extern char* getPathToMyself();

Added: users/rhwood/Pallet/Launcher.m
===================================================================
--- users/rhwood/Pallet/Launcher.m	                        (rev 0)
+++ users/rhwood/Pallet/Launcher.m	2007-03-12 08:51:09 UTC (rev 22706)
@@ -0,0 +1,140 @@
+//
+//  Launcher.m
+//  Pallet
+//
+//  Created by Randall Hansen Wood on 27/12/2006.
+//  Copyright 2006 __MyCompanyName__. All rights reserved.
+//
+
+#include <sys/stat.h>
+
+#import "Launcher.h"
+
+extern char* getPathToMyself();
+
+#define BUFSIZE 4096
+
+enum {
+    cmdAuthorized,
+    cmdNotAuthorized,
+    cmdStatusUndetermined,
+    cmdNotOwnedByRoot
+};
+
+int selfRepair() {
+	AuthorizationRef authorization;
+    struct stat st;
+    int fd_tool;
+    int result = FALSE;
+    int resrep = TRUE;
+	int chownerr = 0;
+	int chmoderr;
+    char* path_to_self = getPathToMyself();
+    char path_to_res[BUFSIZE];
+    char* end_of_dir;
+
+#ifndef DEBUGGING
+	resrep = FALSE;
+    //* Get path to Resource directory *
+    strcpy(path_to_res, path_to_self);
+    end_of_dir = strrchr(path_to_res, '/');
+    if (end_of_dir == NULL) path_to_res[0] = 0;  //* signal failure *
+    else *end_of_dir = 0;  //* terminate string at slash *
+#endif //DEBUGGING
+    if (path_to_self != NULL){
+        //* Recover the passed in AuthorizationRef. *
+        if (AuthorizationCopyPrivilegedReference(&authorization, kAuthorizationFlagDefaults)
+            == errAuthorizationSuccess){
+			
+            //* Open tool exclusively, so no one can change it while we bless it *
+            fd_tool = open(path_to_self, O_NONBLOCK|O_RDONLY|O_EXLOCK, 0);
+            if ((fd_tool != -1) && (fstat(fd_tool, &st) == 0)){
+                if (st.st_uid != 0)
+                    chownerr = fchown(fd_tool, 0, st.st_gid);
+				
+                //* Disable group and world writability and make setuid root. *
+                chmoderr = fchmod(fd_tool, (st.st_mode & (~(S_IWGRP|S_IWOTH))) | S_ISUID);
+                close(fd_tool);
+				if (0 == chownerr && 0 == chmoderr){
+					result = TRUE;
+				}
+            }
+#ifndef DEBUGGING
+			//* Set ownership of Resource directory to root and disable group and world
+			//	writability *
+			if (path_to_res[0] != 0){
+				if (stat(path_to_res, &st) == 0){
+					chownerr = chown(path_to_res, 0, st.st_gid);
+					chmoderr = chmod(path_to_res, st.st_mode & (~(S_IWGRP|S_IWOTH)));
+					if (0 == chownerr && 0 == chmoderr){
+						resrep = TRUE;
+					}
+				}
+			}
+#endif //DEBUGGING
+		}else{
+			fprintf(stderr, "Authentication as administrator failed.\n");
+		}
+		free(path_to_self);
+    }else{
+		fprintf(stderr, "Unable to determine path to setuid tool.\n");
+    }
+	
+    if (result && resrep){
+		fprintf(stderr, "Self-repair succeeded\n");
+    }else if (result){
+		fprintf(stderr, "/n/nWARNING:  Unable to modify Resource directory\n");
+    }else{
+		fprintf(stderr, "/n/nERROR:  Self-repair failed.  Please be sure you are running Pallet from a directory and disk you are authorized to modify (e.g., not a disk image).\n");
+    }
+    return ! result;  //will be used as exit code; so return 0 if successful, 1 otherwise	
+}
+
+int main(int argc, char * const *argv) {
+	AuthorizationRef *authorization;
+	AuthorizationExternalForm *externalAuthorization;
+	int result = 1;
+	
+	if (read(0, &externalAuthorization, sizeof(externalAuthorization)) == sizeof(externalAuthorization)) {
+		if (AuthorizationCreateFromExternalForm(externalAuthorization, authorization) == errAuthorizationSuccess) {
+			if (argc == 2 && [[[[NSProcessInfo processInfo] arguments] objectAtIndex:1] isEqualToString:@"--self-repair"]) {
+				result = selfRepair();
+			} else if (geteuid() != 0) {
+				result = relaunchForSelfRepair(&authorization);
+			} else {
+				if (!authorizedToExecute(&authorization, [[[NSProcessInfo processInfo] arguments] objectAtIndex:1])) {
+					seteuid(geteuid());
+				}
+				if (argc == 3 && [[[[NSProcessInfo processInfo] arguments] objectAtIndex:1] isEqualToString:@"--kill"]) {
+					pid_t pid = (pid_t)[[[[NSProcessInfo processInfo] arguments] objectAtIndex:2] intValue];
+					NSLog(@"Killing process %s", argv[2]);
+					result = killLauncher(pid, SIGKILL);
+				} else if (argc == 3 && [[[[NSProcessInfo processInfo] arguments] objectAtIndex:1] isEqualToString:@"--write-port-conf"]) {
+					result = writePortConf([[[NSProcessInfo processInfo] arguments] objectAtIndex:2]);
+				} else {
+					int pgid;
+					pgid = (int)getpgrp();
+					NSLog(@"PGID=%d", pgid);
+					switch (isAuthorized([[NSProcessInfo processInfo] arguments])) {
+						case cmdAuthorized:
+							result = perform([[NSProcessInfo processInfo] arguments]);
+							break;
+						case cmdNotAuthorized:
+							NSLog(@"WARNING: An attempt was made to use the Launcher tool in Pallet to run an unauthorized command: %s\n", [[[NSProcessInfo processInfo] arguments] objectAtIndex:1]);
+							break;
+						case cmdStatusUndetermined:
+							NSLog(@"ERROR:  Pallet was unable to determine the owner of %s.\nFor security reasons, Pallet will not run %s unless it can determine that it is owned by root.\n", [[[NSProcessInfo processInfo] arguments] objectAtIndex:1], [[[NSProcessInfo processInfo] arguments] objectAtIndex:1]);
+							break;
+						case cmdNotOwnedByRoot:
+							NSLog(@"ERROR:  %s is not owned by root.\nFor security reasons, Pallet will not run %s unless it is owned by root.\n", [[[NSProcessInfo processInfo] arguments] objectAtIndex:1], [[[NSProcessInfo processInfo] arguments] objectAtIndex:1]);
+							break;
+					}
+				}
+			}
+			exit(result);
+		}
+	}
+
+	NSLog(@"Failed to read authorization from stdin\n");
+	exit(1);
+}
\ No newline at end of file

Added: users/rhwood/Pallet/Launcher_Prefix.pch
===================================================================
--- users/rhwood/Pallet/Launcher_Prefix.pch	                        (rev 0)
+++ users/rhwood/Pallet/Launcher_Prefix.pch	2007-03-12 08:51:09 UTC (rev 22706)
@@ -0,0 +1,36 @@
+//
+// Prefix header for all source files of the 'Launcher' target in the 'Pallet' project
+//
+#ifdef __OBJC__
+	#import <AppKit/AppKit.h>
+	#import <Cocoa/Cocoa.h>
+	#import <Foundation/Foundation.h>
+	#import <Security/Authorization.h>
+	#import <Security/AuthorizationTags.h>
+#endif
+
+#include <sys/types.h>
+
+#include <assert.h>
+#include <crt_externs.h>
+#include <errno.h>
+#include <fnmatch.h>
+#include <mach-o/dyld.h>
+#include <math.h>
+#include <regex.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/errno.h>
+#include <sys/fcntl.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+/*
+#ifndef PORT_PREFIX
+	#define PORT_PREFIX /opt/local
+#endif
+ */
\ No newline at end of file

Added: users/rhwood/Pallet/MPPort.h
===================================================================
--- users/rhwood/Pallet/MPPort.h	                        (rev 0)
+++ users/rhwood/Pallet/MPPort.h	2007-03-12 08:51:09 UTC (rev 22706)
@@ -0,0 +1,31 @@
+/* MPPort */
+
+#import <Cocoa/Cocoa.h>
+
+ at interface MPPort : NSMutableDictionary
+{
+}
+
+- (NSString *)name;
+- (void)setName:(NSString *)name;
+
+- (NSString *)version;
+- (void)setVersion:(NSString *)version;
+
+- (NSString *)revision;
+- (void)setRevision:(NSString *)revision;
+
+- (NSString *)epoch;
+- (NSString *)maintainers;
+- (NSString *)platforms;
+- (NSString *)description;
+- (NSString *)long_description;
+- (NSString *)categories;
+- (NSString *)portdir;
+- (NSString *)variants;
+- (NSString *)status;
+- (NSString *)homepage;
+
+- (NSString *)compositeVersion;
+
+ at end

Added: users/rhwood/Pallet/MPPort.m
===================================================================
--- users/rhwood/Pallet/MPPort.m	                        (rev 0)
+++ users/rhwood/Pallet/MPPort.m	2007-03-12 08:51:09 UTC (rev 22706)
@@ -0,0 +1,25 @@
+#import "MPPort.h"
+
+ at implementation MPPort
+
+- (NSString *)name
+{
+	return [self valueForKey:@"name"];
+}
+
+- (NSString *)version
+{
+	return [self valueForKey:@"verison"];
+}
+
+- (NSString *)revision
+{
+	return [self valueForKey:@"revision"];
+}
+
+- (NSString *)compositeVersion
+{
+	return [[[self version] stringByAppendingString:@"_"] stringByAppendingString:[self revision]];
+}
+
+ at end

Added: users/rhwood/Pallet/MPPortsController.h
===================================================================
--- users/rhwood/Pallet/MPPortsController.h	                        (rev 0)
+++ users/rhwood/Pallet/MPPortsController.h	2007-03-12 08:51:09 UTC (rev 22706)
@@ -0,0 +1,14 @@
+/* MPPortsController */
+
+#import <Cocoa/Cocoa.h>
+
+ at interface MPPortsController : NSArrayController
+{
+	NSString *searchString;
+}
+
+- (IBAction)search:(id)sender;
+- (void)setSearchString:(NSString *)aString;
+- (NSString *)searchString;
+
+ at end

Added: users/rhwood/Pallet/MPPortsController.m
===================================================================
--- users/rhwood/Pallet/MPPortsController.m	                        (rev 0)
+++ users/rhwood/Pallet/MPPortsController.m	2007-03-12 08:51:09 UTC (rev 22706)
@@ -0,0 +1,47 @@
+#import "MPPortsController.h"
+
+ at implementation MPPortsController
+
+- (NSArray *)arrangeObjects:(NSArray *)objects
+{
+	if (searchString == nil || [searchString isEqualToString:@""]) {
+		return [super arrangeObjects:objects];
+	}
+	
+	NSMutableArray *filteredObjects = [NSMutableArray arrayWithCapacity:[objects count]];
+	NSEnumerator *objectsEnumerator = [objects objectEnumerator];
+	id item;
+	
+	while (item = [objectsEnumerator nextObject]) {
+		if ([[item valueForKeyPath:@"name"] rangeOfString:searchString options:NSCaseInsensitiveSearch].location != NSNotFound ||
+			[[item valueForKeyPath:@"categories"] rangeOfString:searchString options:NSCaseInsensitiveSearch].location != NSNotFound ||
+			[[item valueForKeyPath:@"description"] rangeOfString:searchString options:NSCaseInsensitiveSearch].location != NSNotFound ||
+			[[item valueForKeyPath:@"long_description"] rangeOfString:searchString options:NSCaseInsensitiveSearch].location != NSNotFound ||
+			[[item valueForKeyPath:@"homepage"] rangeOfString:searchString options:NSCaseInsensitiveSearch].location != NSNotFound ||
+			[[item valueForKeyPath:@"maintainers"] rangeOfString:searchString options:NSCaseInsensitiveSearch].location != NSNotFound
+			) {
+			[filteredObjects addObject:item];
+		}
+	}
+	return [super arrangeObjects:filteredObjects];
+}
+
+- (IBAction)search:(id)sender
+{
+	[self setSearchString:[sender stringValue]];
+	[self rearrangeObjects];
+}
+
+- (void)setSearchString:(NSString *)aString
+{
+	[aString retain];
+	[searchString release];
+	searchString = aString;
+}
+
+- (NSString *)searchString
+{
+	return searchString;
+}
+
+ at end

Added: users/rhwood/Pallet/MPToolbar.h
===================================================================
--- users/rhwood/Pallet/MPToolbar.h	                        (rev 0)
+++ users/rhwood/Pallet/MPToolbar.h	2007-03-12 08:51:09 UTC (rev 22706)
@@ -0,0 +1,64 @@
+/*
+	Class MPToolbar
+	Project Pallet
+ 
+	Copyright (C) 2006 MacPorts.
+ 
+	This code is free software; you can redistribute it and/or modify it under
+	the terms of the GNU General Public License as published by the Free
+	Software Foundation; either version 2 of the License, or any later version.
+ 
+	This code is distributed in the hope that it will be useful, but WITHOUT ANY
+	WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+	FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+	details.
+ 
+	For a copy of the GNU General Public License, visit <http://www.gnu.org/> or
+	write to the Free Software Foundation, Inc., 59 Temple Place--Suite 330,
+	Boston, MA 02111-1307, USA.
+ 
+	More information is available at http://www.macports.org or macports-users at lists.macosforge.org
+ 
+	History:
+	
+	Created by Randall Wood rhwood at macports.org on 6 October 2006
+ */
+
+#import <Cocoa/Cocoa.h>
+
+ at class MPAuthority;
+
+ at interface MPToolbar : NSObject {
+
+	IBOutlet NSWindow *ports;
+	IBOutlet MPAuthority *portAuthority;
+	IBOutlet NSSearchField *searchField;
+	IBOutlet NSView *searchView;
+
+	NSMutableDictionary *toolbarItems;
+	NSToolbarItem *toolbarSearchItem;
+
+	
+	
+}
+
+- (IBAction)search:(id)sender;
+
+- (BOOL)validateMenuItem:(NSMenuItem*)anItem;
+
+- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag;
+- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar*)toolbar;
+- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar*)toolbar;
+- (BOOL)validateToolbarItem:(NSToolbarItem *)theItem;
+- (void)addItemToToolbar:(NSString *)identifier
+				   label:(NSString *)label
+			paletteLabel:(NSString *)paletteLabel
+				 toolTip:(NSString *)toolTip
+				  target:(id)target
+				  action:(SEL)action
+		 settingSelector:(SEL)settingSelector
+			 itemContent:(id)itemContent
+					menu:(NSMenu *)menu;
+
+
+ at end

Added: users/rhwood/Pallet/MPToolbar.m
===================================================================
--- users/rhwood/Pallet/MPToolbar.m	                        (rev 0)
+++ users/rhwood/Pallet/MPToolbar.m	2007-03-12 08:51:09 UTC (rev 22706)
@@ -0,0 +1,219 @@
+/*
+	Class MPToolbar
+	Project Pallet
+ 
+	Copyright (C) 2006 MacPorts.
+ 
+	This code is free software; you can redistribute it and/or modify it under
+	the terms of the GNU General Public License as published by the Free
+	Software Foundation; either version 2 of the License, or any later version.
+ 
+	This code is distributed in the hope that it will be useful, but WITHOUT ANY
+	WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+	FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+	details.
+ 
+	For a copy of the GNU General Public License, visit <http://www.gnu.org/> or
+	write to the Free Software Foundation, Inc., 59 Temple Place--Suite 330,
+	Boston, MA 02111-1307, USA.
+ 
+	More information is available at http://www.macports.org or macports-users at lists.macosforge.org
+ 
+	History:
+	
+	Created by Randall Wood rhwood at macports.org on 6 October 2006
+ */
+
+#import "MPToolbar.h"
+
+
+ at implementation MPToolbar
+
+- (void)awakeFromNib
+{
+	[[searchField cell] setSearchMenuTemplate:[[searchField cell] searchMenuTemplate]];
+	NSToolbar *toolbar = [[[NSToolbar alloc] initWithIdentifier:@"myToolbar"] autorelease];
+	toolbarItems = [[NSMutableDictionary dictionary] retain];
+	toolbarSearchItem = [[[NSToolbarItem alloc] init] retain];
+	[self addItemToToolbar:@"Install"
+					 label:NSLocalizedString(@"Install", @"Install label")
+			  paletteLabel:NSLocalizedString(@"Install Port", @"Install paletteLabel")
+				   toolTip:NSLocalizedString(@"Install the selected port", @"Install toolTip")
+					target:portAuthority
+					action:@selector(installPort:)
+		   settingSelector:@selector(setImage:)
+			   itemContent:[NSImage imageNamed:@"Install.tiff"]
+					  menu:NULL];
+	[self addItemToToolbar:@"Remove"
+					 label:NSLocalizedString(@"Remove", @"Remove label")
+			  paletteLabel:NSLocalizedString(@"Remove Port", @"Remove paletteLabel")
+				   toolTip:NSLocalizedString(@"Remove the selected port", @"Remove toolTip")
+					target:portAuthority
+					action:@selector(removePort:)
+		   settingSelector:@selector(setImage:)
+			   itemContent:[NSImage imageNamed:@"Remove.tiff"]
+					  menu:NULL];
+	[self addItemToToolbar:@"Halt"
+					 label:NSLocalizedString(@"Halt", @"Halt label")
+			  paletteLabel:NSLocalizedString(@"Halt Command", @"Halt paletteLabel")
+				   toolTip:NSLocalizedString(@"Halt the command being executed", @"Halt toolTip")
+					target:portAuthority
+					action:@selector(halt:)
+		   settingSelector:@selector(setImage:)
+			   itemContent:[NSImage imageNamed:@"Halt.tiff"]
+					  menu:NULL];
+	[self addItemToToolbar:@"Sync"
+					 label:NSLocalizedString(@"Sync", @"Sync label")
+			  paletteLabel:NSLocalizedString(@"Sync Ports List", @"Sync paletteLabel")
+				   toolTip:NSLocalizedString(@"Synchronize the list of available ports", @"Sync toolTip")
+					target:portAuthority
+					action:@selector(syncPortsList:)
+		   settingSelector:@selector(setImage:)
+			   itemContent:[NSImage imageNamed:@"Sync.tiff"]
+					  menu:NULL];
+	[self addItemToToolbar:@"Upgrade"
+					 label:NSLocalizedString(@"Upgrade", @"Upgrade label")
+			  paletteLabel:NSLocalizedString(@"Upgrade Port", @"Upgrade paletteLabel")
+				   toolTip:NSLocalizedString(@"Upgrade the selected port", @"Upgrade toolTip")
+					target:portAuthority
+					action:@selector(upgradePort:)
+		   settingSelector:@selector(setImage:)
+			   itemContent:[NSImage imageNamed:@"Upgrade.tiff"]
+					  menu:NULL];
+	[self addItemToToolbar:@"Update"
+					 label:NSLocalizedString(@"Update", @"Update label")
+			  paletteLabel:NSLocalizedString(@"Update MacPorts", @"Update paletteLabel")
+				   toolTip:NSLocalizedString(@"Update the MacPorts infrastructure", @"Update toolTip")
+					target:portAuthority
+					action:@selector(updateMacPorts:)
+		   settingSelector:@selector(setImage:)
+			   itemContent:[NSImage imageNamed:@"Update.tiff"]
+					  menu:NULL];
+	[self addItemToToolbar:@"Search"
+					 label:NSLocalizedString(@"Search", @"Search label")
+			  paletteLabel:NSLocalizedString(@"Search Ports", @"Search paletteLabel")
+				   toolTip:NSLocalizedString(@"Search for a port", @"Search toolTip")
+					target:portAuthority
+					action:NULL
+		   settingSelector:@selector(setView:)
+			   itemContent:searchView
+					  menu:NULL];
+    [toolbar setDelegate:self];
+    [toolbar setAllowsUserCustomization:YES];
+    [toolbar setAutosavesConfiguration: YES]; 
+    [toolbar setDisplayMode: NSToolbarDisplayModeDefault];
+    [ports setToolbar:toolbar];
+}
+
+- (void) dealloc
+{
+    [toolbarItems release];
+	[toolbarSearchItem release];
+    [super dealloc];
+}
+
+- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag
+{
+    // We create and autorelease a new NSToolbarItem, and then go through the process of setting up its
+    // attributes from the master toolbar item matching that identifier in our dictionary of items.
+    NSToolbarItem *newItem = [[[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier] autorelease];
+    NSToolbarItem *item = [toolbarItems objectForKey:itemIdentifier];
+    
+    [newItem setLabel:[item label]];
+    [newItem setPaletteLabel:[item paletteLabel]];
+    if ([item view] != NULL) {
+		[newItem setView:[item view]];
+    } else {
+		[newItem setImage:[item image]];
+    }
+    [newItem setToolTip:[item toolTip]];
+    [newItem setTarget:[item target]];
+    [newItem setAction:[item action]];
+    [newItem setMenuFormRepresentation:[item menuFormRepresentation]];
+    // If we have a custom view, we *have* to set the min/max size - otherwise, it'll default to 0,0 and the custom
+    // view won't show up at all!  This doesn't affect toolbar items with images, however.
+    if ([newItem view] != NULL) {
+		[newItem setMinSize:[[item view] bounds].size];
+		[newItem setMaxSize:[[item view] bounds].size];
+    }
+	// Grab a reference to the search item so we can manipulate its label
+	if ([itemIdentifier isEqualToString:@"Search"]) {
+		[toolbarSearchItem release];
+		toolbarSearchItem = newItem;
+	}
+    return newItem;
+}
+
+- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar*)toolbar
+{
+	return [NSArray arrayWithObjects:
+		@"Install",
+		@"Remove",
+		@"Upgrade",
+		NSToolbarSeparatorItemIdentifier,
+		@"Sync",
+		@"Halt",
+		NSToolbarFlexibleSpaceItemIdentifier,
+		@"Search",
+		nil];
+}
+
+- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar*)toolbar
+{
+    return [NSArray arrayWithObjects:
+		@"Install",
+		@"Remove", 
+		@"Halt",
+		@"Search",
+		@"Sync",
+		@"Update",
+		@"Upgrade",
+		NSToolbarSeparatorItemIdentifier,
+		NSToolbarSpaceItemIdentifier,
+		NSToolbarFlexibleSpaceItemIdentifier,
+		nil];
+}
+
+- (BOOL)validateToolbarItem:(NSToolbarItem *)theItem
+{
+	return YES;
+}
+
+- (void)addItemToToolbar:(NSString *)identifier
+				   label:(NSString *)label
+			paletteLabel:(NSString *)paletteLabel
+				 toolTip:(NSString *)toolTip
+				  target:(id)target
+				  action:(SEL)action
+		 settingSelector:(SEL)settingSelector
+			 itemContent:(id)itemContent
+					menu:(NSMenu *)menu
+{
+    NSMenuItem *menuItem;
+    NSToolbarItem *item = [[[NSToolbarItem alloc] initWithItemIdentifier:identifier] autorelease];
+    [item setLabel:label];
+    [item setPaletteLabel:paletteLabel];
+    [item setToolTip:toolTip];
+    [item setTarget:target];
+    [item performSelector:settingSelector withObject:itemContent];
+    [item setAction:action];
+    if (menu != NULL) {
+		menuItem=[[[NSMenuItem alloc] init] autorelease];
+		[menuItem setSubmenu: menu];
+		[menuItem setTitle: [menu title]];
+		[item setMenuFormRepresentation:menuItem];
+    }
+    [toolbarItems setObject:item forKey:identifier];
+}
+
+- (BOOL)validateMenuItem:(NSMenuItem*)anItem
+{
+	return YES;
+}
+
+- (IBAction)search:(id)sender
+{
+	
+}
+
+ at end

Added: users/rhwood/Pallet/PAStatusTransformer.h
===================================================================
--- users/rhwood/Pallet/PAStatusTransformer.h	                        (rev 0)
+++ users/rhwood/Pallet/PAStatusTransformer.h	2007-03-12 08:51:09 UTC (rev 22706)
@@ -0,0 +1,23 @@
+//
+//  PAStatusTransformer.h
+//  Pallet
+//
+//  Created by Randall Hansen Wood on 13/1/2007.
+//  Copyright 2007 __MyCompanyName__. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "PortAuthority.h"
+
+enum portStatuses {
+	portStatusInstalled,
+	portStatusActive,
+	portStatusOutdated,
+	portStatusUnknown
+};
+
+ at interface PAStatusTransformer : NSValueTransformer
+{
+}
+
+ at end

Added: users/rhwood/Pallet/PAStatusTransformer.m
===================================================================
--- users/rhwood/Pallet/PAStatusTransformer.m	                        (rev 0)
+++ users/rhwood/Pallet/PAStatusTransformer.m	2007-03-12 08:51:09 UTC (rev 22706)
@@ -0,0 +1,45 @@
+//
+//  PAStatusTransformer.m
+//  Pallet
+//
+//  Created by Randall Hansen Wood on 13/1/2007.
+//  Copyright 2007 __MyCompanyName__. All rights reserved.
+//
+
+#import "PAStatusTransformer.h"
+
+
+ at implementation PAStatusTransformer
+
++ (Class)transformedValueClass
+{
+	return [NSString self];
+}
+
++ (BOOL)allowsReverseTransformation
+{
+	return NO;
+}
+
+- (id)transformedValue:(id)beforeObject
+{
+	if (beforeObject == nil) return nil;
+	id resourcePath = [[NSBundle mainBundle] resourcePath];
+	switch ([beforeObject intValue]) {
+		case portStatusUnknown:
+			return nil;
+			break;
+		case portStatusActive:
+			return [resourcePath stringByAppendingPathComponent:@"active.gif"];
+			break;
+		case portStatusInstalled:
+			return [resourcePath stringByAppendingPathComponent:@"installed.gif"];
+			break;
+		case portStatusOutdated:
+			return [resourcePath stringByAppendingPathComponent:@"outdated.gif"];
+			break;
+	}
+	return nil;
+}
+
+ at end

Added: users/rhwood/Pallet/Pallet.pmproj
===================================================================
(Binary files differ)


Property changes on: users/rhwood/Pallet/Pallet.pmproj
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: users/rhwood/Pallet/Pallet.xcodeproj/project.pbxproj
===================================================================
--- users/rhwood/Pallet/Pallet.xcodeproj/project.pbxproj	                        (rev 0)
+++ users/rhwood/Pallet/Pallet.xcodeproj/project.pbxproj	2007-03-12 08:51:09 UTC (rev 22706)
@@ -0,0 +1,511 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 42;
+	objects = {
+
+/* Begin PBXBuildFile section */
+		480062BF0B597D9A005F27E4 /* PAStatusTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 480062BE0B597D9A005F27E4 /* PAStatusTransformer.m */; };
+		481B84120BA254A4000D1385 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4854CE0F0B420D8C00950EE4 /* Security.framework */; };
+		4828C6310AD7B84D002AF0DD /* TaskWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4828C6300AD7B84D002AF0DD /* TaskWrapper.m */; };
+		483A5E460B57A50900712840 /* MPPortsController.m in Sources */ = {isa = PBXBuildFile; fileRef = 483A5E450B57A50900712840 /* MPPortsController.m */; };
+		4844B92B0AD91F5800A4A4DB /* UserDefaults.plist in Resources */ = {isa = PBXBuildFile; fileRef = 4844B92A0AD91F5800A4A4DB /* UserDefaults.plist */; };
+		4875A7410B468DEB00FDDC21 /* ApplicationIconBusy.icns in Resources */ = {isa = PBXBuildFile; fileRef = 4875A7400B468DEB00FDDC21 /* ApplicationIconBusy.icns */; };
+		4875A77A0B46955800FDDC21 /* Launcher in Resources */ = {isa = PBXBuildFile; fileRef = 48ACD78B0B42846B00D34B4C /* Launcher */; };
+		4875A9520B4839AA00FDDC21 /* outdated.gif in Resources */ = {isa = PBXBuildFile; fileRef = 4875A9510B4839AA00FDDC21 /* outdated.gif */; };
+		4875A9540B4839C000FDDC21 /* active.gif in Resources */ = {isa = PBXBuildFile; fileRef = 4875A9530B4839C000FDDC21 /* active.gif */; };
+		4875A9560B4839D700FDDC21 /* installed.gif in Resources */ = {isa = PBXBuildFile; fileRef = 4875A9550B4839D700FDDC21 /* installed.gif */; };
+		487EB9170B45335D001B0F72 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
+		487EB9270B4533BC001B0F72 /* Launcher.c in Sources */ = {isa = PBXBuildFile; fileRef = 48BBCE7D0B41B2450063A19F /* Launcher.c */; };
+		487EB9280B4533CB001B0F72 /* getpath.c in Sources */ = {isa = PBXBuildFile; fileRef = 48BBCE870B41B37F0063A19F /* getpath.c */; };
+		487EB9490B453786001B0F72 /* AuthorizedExecutable.m in Sources */ = {isa = PBXBuildFile; fileRef = 487EB9480B453786001B0F72 /* AuthorizedExecutable.m */; };
+		48ACD7930B4284A400D34B4C /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4854CE0F0B420D8C00950EE4 /* Security.framework */; };
+		48D470190AD6867C00352CE9 /* PortAuthority.m in Sources */ = {isa = PBXBuildFile; fileRef = 48D470180AD6867C00352CE9 /* PortAuthority.m */; };
+		48D470790AD6CFFB00352CE9 /* MPToolbar.m in Sources */ = {isa = PBXBuildFile; fileRef = 48D470780AD6CFFB00352CE9 /* MPToolbar.m */; };
+		48D470C90AD7256700352CE9 /* Remove.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 48D470C70AD7256600352CE9 /* Remove.tiff */; };
+		48D470CA0AD7256700352CE9 /* Halt.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 48D470C80AD7256700352CE9 /* Halt.tiff */; };
+		48D4718D0AD73ECD00352CE9 /* Sync.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 48D4718A0AD73ECD00352CE9 /* Sync.tiff */; };
+		48D4718E0AD73ECD00352CE9 /* Update.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 48D4718B0AD73ECD00352CE9 /* Update.tiff */; };
+		48D4718F0AD73ECD00352CE9 /* Upgrade.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 48D4718C0AD73ECD00352CE9 /* Upgrade.tiff */; };
+		48D471FB0AD7A99500352CE9 /* Install.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 48D471FA0AD7A99500352CE9 /* Install.tiff */; };
+		48D4721F0AD7B10600352CE9 /* ApplicationIcon.icns in Resources */ = {isa = PBXBuildFile; fileRef = 48D4721E0AD7B10600352CE9 /* ApplicationIcon.icns */; };
+		48EE4F7D0B515B7D0066DCBA /* Tcl.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 48EE4F7C0B515B7D0066DCBA /* Tcl.framework */; };
+		8D11072A0486CEB800E47090 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 29B97318FDCFA39411CA2CEA /* MainMenu.nib */; };
+		8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; };
+		8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; };
+		8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+		4875A8BD0B46FE9000FDDC21 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 48ACD78A0B42846B00D34B4C;
+			remoteInfo = Launcher;
+		};
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+		089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+		1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
+		13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
+		29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+		29B97319FDCFA39411CA2CEA /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/MainMenu.nib; sourceTree = "<group>"; };
+		29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
+		29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
+		32CA4F630368D1EE00C91783 /* Port Authority_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Port Authority_Prefix.pch"; sourceTree = "<group>"; };
+		4800621E0B58FB31005F27E4 /* MPPort.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = MPPort.m; sourceTree = "<group>"; };
+		4800621F0B58FB31005F27E4 /* MPPort.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MPPort.h; sourceTree = "<group>"; };
+		480062BD0B597D9A005F27E4 /* PAStatusTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PAStatusTransformer.h; sourceTree = "<group>"; };
+		480062BE0B597D9A005F27E4 /* PAStatusTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PAStatusTransformer.m; sourceTree = "<group>"; };
+		4828C62F0AD7B84D002AF0DD /* TaskWrapper.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TaskWrapper.h; sourceTree = "<group>"; };
+		4828C6300AD7B84D002AF0DD /* TaskWrapper.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = TaskWrapper.m; sourceTree = "<group>"; };
+		483A5E440B57A50900712840 /* MPPortsController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MPPortsController.h; sourceTree = "<group>"; };
+		483A5E450B57A50900712840 /* MPPortsController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = MPPortsController.m; sourceTree = "<group>"; };
+		4844B92A0AD91F5800A4A4DB /* UserDefaults.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = UserDefaults.plist; sourceTree = "<group>"; };
+		4854CE0F0B420D8C00950EE4 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = /System/Library/Frameworks/Security.framework; sourceTree = "<absolute>"; };
+		4854CE6A0B42107000950EE4 /* Launcher_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Launcher_Prefix.pch; sourceTree = "<group>"; };
+		4875A7400B468DEB00FDDC21 /* ApplicationIconBusy.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = ApplicationIconBusy.icns; sourceTree = "<group>"; };
+		4875A9510B4839AA00FDDC21 /* outdated.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = outdated.gif; sourceTree = "<group>"; };
+		4875A9530B4839C000FDDC21 /* active.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = active.gif; sourceTree = "<group>"; };
+		4875A9550B4839D700FDDC21 /* installed.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = installed.gif; sourceTree = "<group>"; };
+		487EB9470B453785001B0F72 /* AuthorizedExecutable.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AuthorizedExecutable.h; sourceTree = "<group>"; };
+		487EB9480B453786001B0F72 /* AuthorizedExecutable.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = AuthorizedExecutable.m; sourceTree = "<group>"; };
+		48ACD78B0B42846B00D34B4C /* Launcher */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Launcher; sourceTree = BUILT_PRODUCTS_DIR; };
+		48ACD7D10B42855600D34B4C /* Launcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Launcher.h; sourceTree = "<group>"; };
+		48ACD7D20B42855600D34B4C /* Launcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Launcher.m; sourceTree = "<group>"; };
+		48AFB8B70BA4E20300896AF1 /* Debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Debug.h; sourceTree = "<group>"; };
+		48BBCE7D0B41B2450063A19F /* Launcher.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Launcher.c; sourceTree = "<group>"; };
+		48BBCE870B41B37F0063A19F /* getpath.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = getpath.c; sourceTree = "<group>"; };
+		48D470170AD6867B00352CE9 /* PortAuthority.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PortAuthority.h; sourceTree = "<group>"; };
+		48D470180AD6867C00352CE9 /* PortAuthority.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = PortAuthority.m; sourceTree = "<group>"; };
+		48D470770AD6CFFB00352CE9 /* MPToolbar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPToolbar.h; sourceTree = "<group>"; };
+		48D470780AD6CFFB00352CE9 /* MPToolbar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPToolbar.m; sourceTree = "<group>"; };
+		48D470C70AD7256600352CE9 /* Remove.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = Remove.tiff; sourceTree = "<group>"; };
+		48D470C80AD7256700352CE9 /* Halt.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = Halt.tiff; sourceTree = "<group>"; };
+		48D4718A0AD73ECD00352CE9 /* Sync.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = Sync.tiff; sourceTree = "<group>"; };
+		48D4718B0AD73ECD00352CE9 /* Update.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = Update.tiff; sourceTree = "<group>"; };
+		48D4718C0AD73ECD00352CE9 /* Upgrade.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = Upgrade.tiff; sourceTree = "<group>"; };
+		48D471FA0AD7A99500352CE9 /* Install.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = Install.tiff; sourceTree = "<group>"; };
+		48D4721E0AD7B10600352CE9 /* ApplicationIcon.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = ApplicationIcon.icns; sourceTree = "<group>"; };
+		48EE4F7C0B515B7D0066DCBA /* Tcl.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Tcl.framework; path = /System/Library/Frameworks/Tcl.framework; sourceTree = "<absolute>"; };
+		8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
+		8D1107320486CEB800E47090 /* Pallet.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = Pallet.app; sourceTree = BUILT_PRODUCTS_DIR; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		48ACD7890B42846B00D34B4C /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				487EB9170B45335D001B0F72 /* Cocoa.framework in Frameworks */,
+				48ACD7930B4284A400D34B4C /* Security.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		8D11072E0486CEB800E47090 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */,
+				481B84120BA254A4000D1385 /* Security.framework in Frameworks */,
+				48EE4F7D0B515B7D0066DCBA /* Tcl.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		080E96DDFE201D6D7F000001 /* Classes */ = {
+			isa = PBXGroup;
+			children = (
+				487EB9470B453785001B0F72 /* AuthorizedExecutable.h */,
+				487EB9480B453786001B0F72 /* AuthorizedExecutable.m */,
+				4828C62F0AD7B84D002AF0DD /* TaskWrapper.h */,
+				4828C6300AD7B84D002AF0DD /* TaskWrapper.m */,
+				48D470170AD6867B00352CE9 /* PortAuthority.h */,
+				48D470180AD6867C00352CE9 /* PortAuthority.m */,
+				480062BD0B597D9A005F27E4 /* PAStatusTransformer.h */,
+				480062BE0B597D9A005F27E4 /* PAStatusTransformer.m */,
+				48D470770AD6CFFB00352CE9 /* MPToolbar.h */,
+				48D470780AD6CFFB00352CE9 /* MPToolbar.m */,
+				483A5E440B57A50900712840 /* MPPortsController.h */,
+				483A5E450B57A50900712840 /* MPPortsController.m */,
+				4800621E0B58FB31005F27E4 /* MPPort.m */,
+				4800621F0B58FB31005F27E4 /* MPPort.h */,
+			);
+			name = Classes;
+			sourceTree = "<group>";
+		};
+		1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				48EE4F7C0B515B7D0066DCBA /* Tcl.framework */,
+				4854CE0F0B420D8C00950EE4 /* Security.framework */,
+				1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */,
+			);
+			name = "Linked Frameworks";
+			sourceTree = "<group>";
+		};
+		1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				29B97324FDCFA39411CA2CEA /* AppKit.framework */,
+				13E42FB307B3F0F600E4EEF1 /* CoreData.framework */,
+				29B97325FDCFA39411CA2CEA /* Foundation.framework */,
+			);
+			name = "Other Frameworks";
+			sourceTree = "<group>";
+		};
+		19C28FACFE9D520D11CA2CBB /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				8D1107320486CEB800E47090 /* Pallet.app */,
+				48ACD78B0B42846B00D34B4C /* Launcher */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		29B97314FDCFA39411CA2CEA /* Port Authority */ = {
+			isa = PBXGroup;
+			children = (
+				080E96DDFE201D6D7F000001 /* Classes */,
+				29B97315FDCFA39411CA2CEA /* Other Sources */,
+				29B97317FDCFA39411CA2CEA /* Resources */,
+				29B97323FDCFA39411CA2CEA /* Frameworks */,
+				19C28FACFE9D520D11CA2CBB /* Products */,
+			);
+			name = "Port Authority";
+			sourceTree = "<group>";
+		};
+		29B97315FDCFA39411CA2CEA /* Other Sources */ = {
+			isa = PBXGroup;
+			children = (
+				48ACD7D10B42855600D34B4C /* Launcher.h */,
+				48AFB8B70BA4E20300896AF1 /* Debug.h */,
+				48ACD7D20B42855600D34B4C /* Launcher.m */,
+				48BBCE870B41B37F0063A19F /* getpath.c */,
+				48BBCE7D0B41B2450063A19F /* Launcher.c */,
+				4854CE6A0B42107000950EE4 /* Launcher_Prefix.pch */,
+				32CA4F630368D1EE00C91783 /* Port Authority_Prefix.pch */,
+				29B97316FDCFA39411CA2CEA /* main.m */,
+			);
+			name = "Other Sources";
+			sourceTree = "<group>";
+		};
+		29B97317FDCFA39411CA2CEA /* Resources */ = {
+			isa = PBXGroup;
+			children = (
+				4875A7400B468DEB00FDDC21 /* ApplicationIconBusy.icns */,
+				48D4721E0AD7B10600352CE9 /* ApplicationIcon.icns */,
+				48D471FA0AD7A99500352CE9 /* Install.tiff */,
+				48D4718A0AD73ECD00352CE9 /* Sync.tiff */,
+				48D4718B0AD73ECD00352CE9 /* Update.tiff */,
+				48D4718C0AD73ECD00352CE9 /* Upgrade.tiff */,
+				48D470C70AD7256600352CE9 /* Remove.tiff */,
+				48D470C80AD7256700352CE9 /* Halt.tiff */,
+				8D1107310486CEB800E47090 /* Info.plist */,
+				089C165CFE840E0CC02AAC07 /* InfoPlist.strings */,
+				29B97318FDCFA39411CA2CEA /* MainMenu.nib */,
+				4875A9550B4839D700FDDC21 /* installed.gif */,
+				4875A9530B4839C000FDDC21 /* active.gif */,
+				4875A9510B4839AA00FDDC21 /* outdated.gif */,
+				4844B92A0AD91F5800A4A4DB /* UserDefaults.plist */,
+			);
+			name = Resources;
+			sourceTree = "<group>";
+		};
+		29B97323FDCFA39411CA2CEA /* Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */,
+				1058C7A2FEA54F0111CA2CBB /* Other Frameworks */,
+			);
+			name = Frameworks;
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+		48ACD78A0B42846B00D34B4C /* Launcher */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 48ACD78D0B42848A00D34B4C /* Build configuration list for PBXNativeTarget "Launcher" */;
+			buildPhases = (
+				48ACD7880B42846B00D34B4C /* Sources */,
+				48ACD7890B42846B00D34B4C /* Frameworks */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = Launcher;
+			productName = "Privileged Launcher";
+			productReference = 48ACD78B0B42846B00D34B4C /* Launcher */;
+			productType = "com.apple.product-type.tool";
+		};
+		8D1107260486CEB800E47090 /* Pallet */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "Pallet" */;
+			buildPhases = (
+				8D1107290486CEB800E47090 /* Resources */,
+				8D11072C0486CEB800E47090 /* Sources */,
+				8D11072E0486CEB800E47090 /* Frameworks */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				4875A8BE0B46FE9000FDDC21 /* PBXTargetDependency */,
+			);
+			name = Pallet;
+			productInstallPath = "$(HOME)/Applications";
+			productName = "Port Authority";
+			productReference = 8D1107320486CEB800E47090 /* Pallet.app */;
+			productType = "com.apple.product-type.application";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		29B97313FDCFA39411CA2CEA /* Project object */ = {
+			isa = PBXProject;
+			buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Pallet" */;
+			hasScannedForEncodings = 1;
+			mainGroup = 29B97314FDCFA39411CA2CEA /* Port Authority */;
+			projectDirPath = "";
+			targets = (
+				8D1107260486CEB800E47090 /* Pallet */,
+				48ACD78A0B42846B00D34B4C /* Launcher */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+		8D1107290486CEB800E47090 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				4875A77A0B46955800FDDC21 /* Launcher in Resources */,
+				8D11072A0486CEB800E47090 /* MainMenu.nib in Resources */,
+				8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */,
+				48D470C90AD7256700352CE9 /* Remove.tiff in Resources */,
+				48D470CA0AD7256700352CE9 /* Halt.tiff in Resources */,
+				48D4718D0AD73ECD00352CE9 /* Sync.tiff in Resources */,
+				48D4718E0AD73ECD00352CE9 /* Update.tiff in Resources */,
+				48D4718F0AD73ECD00352CE9 /* Upgrade.tiff in Resources */,
+				48D471FB0AD7A99500352CE9 /* Install.tiff in Resources */,
+				48D4721F0AD7B10600352CE9 /* ApplicationIcon.icns in Resources */,
+				4844B92B0AD91F5800A4A4DB /* UserDefaults.plist in Resources */,
+				4875A7410B468DEB00FDDC21 /* ApplicationIconBusy.icns in Resources */,
+				4875A9520B4839AA00FDDC21 /* outdated.gif in Resources */,
+				4875A9540B4839C000FDDC21 /* active.gif in Resources */,
+				4875A9560B4839D700FDDC21 /* installed.gif in Resources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+		48ACD7880B42846B00D34B4C /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				487EB9280B4533CB001B0F72 /* getpath.c in Sources */,
+				487EB9270B4533BC001B0F72 /* Launcher.c in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		8D11072C0486CEB800E47090 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				8D11072D0486CEB800E47090 /* main.m in Sources */,
+				48D470190AD6867C00352CE9 /* PortAuthority.m in Sources */,
+				48D470790AD6CFFB00352CE9 /* MPToolbar.m in Sources */,
+				4828C6310AD7B84D002AF0DD /* TaskWrapper.m in Sources */,
+				487EB9490B453786001B0F72 /* AuthorizedExecutable.m in Sources */,
+				483A5E460B57A50900712840 /* MPPortsController.m in Sources */,
+				480062BF0B597D9A005F27E4 /* PAStatusTransformer.m in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+		4875A8BE0B46FE9000FDDC21 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 48ACD78A0B42846B00D34B4C /* Launcher */;
+			targetProxy = 4875A8BD0B46FE9000FDDC21 /* PBXContainerItemProxy */;
+		};
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+		089C165CFE840E0CC02AAC07 /* InfoPlist.strings */ = {
+			isa = PBXVariantGroup;
+			children = (
+				089C165DFE840E0CC02AAC07 /* English */,
+			);
+			name = InfoPlist.strings;
+			sourceTree = "<group>";
+		};
+		29B97318FDCFA39411CA2CEA /* MainMenu.nib */ = {
+			isa = PBXVariantGroup;
+			children = (
+				29B97319FDCFA39411CA2CEA /* English */,
+			);
+			name = MainMenu.nib;
+			sourceTree = "<group>";
+		};
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+		48ACD78E0B42848A00D34B4C /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				COPY_PHASE_STRIP = NO;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_ENABLE_FIX_AND_CONTINUE = YES;
+				GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+				GCC_MODEL_TUNING = G5;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = "$(inherited)";
+				INSTALL_PATH = "$(HOME)/bin";
+				OTHER_LDFLAGS = (
+					"-framework",
+					Foundation,
+					"-framework",
+					AppKit,
+				);
+				PREBINDING = NO;
+				PRODUCT_NAME = Launcher;
+				ZERO_LINK = YES;
+			};
+			name = Debug;
+		};
+		48ACD78F0B42848A00D34B4C /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ARCHS = (
+					ppc,
+					i386,
+				);
+				COPY_PHASE_STRIP = YES;
+				GCC_ENABLE_FIX_AND_CONTINUE = NO;
+				GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+				GCC_MODEL_TUNING = G4;
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = Launcher_Prefix.pch;
+				INSTALL_PATH = "$(HOME)/bin";
+				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET_i386 = "$(inherited)";
+				MACOSX_DEPLOYMENT_TARGET_ppc = "$(inherited)";
+				OTHER_LDFLAGS = "";
+				PREBINDING = YES;
+				PRODUCT_NAME = Launcher;
+				SKIP_INSTALL = YES;
+				ZERO_LINK = NO;
+			};
+			name = Release;
+		};
+		C01FCF4B08A954540054247B /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				COPY_PHASE_STRIP = NO;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_ENABLE_FIX_AND_CONTINUE = YES;
+				GCC_MODEL_TUNING = G5;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				INFOPLIST_FILE = Info.plist;
+				INSTALL_PATH = "$(HOME)/Applications";
+				PRODUCT_NAME = Pallet;
+				WRAPPER_EXTENSION = app;
+				ZERO_LINK = YES;
+			};
+			name = Debug;
+		};
+		C01FCF4C08A954540054247B /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ARCHS = (
+					ppc,
+					i386,
+				);
+				GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+				GCC_MODEL_TUNING = G4;
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = "Port Authority_Prefix.pch";
+				INFOPLIST_FILE = Info.plist;
+				INSTALL_PATH = /Applications;
+				MACOSX_DEPLOYMENT_TARGET = 10.4;
+				MACOSX_DEPLOYMENT_TARGET_i386 = 10.4;
+				MACOSX_DEPLOYMENT_TARGET_ppc = 10.3;
+				PRODUCT_NAME = Pallet;
+				WRAPPER_EXTENSION = app;
+			};
+			name = Release;
+		};
+		C01FCF4F08A954540054247B /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUGGING=1",
+					"$(inherited)",
+				);
+				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				PREBINDING = NO;
+				SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
+				VERSIONING_SYSTEM = "apple-generic";
+			};
+			name = Debug;
+		};
+		C01FCF5008A954540054247B /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+				GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)";
+				GCC_WARN_ABOUT_RETURN_TYPE = NO;
+				GCC_WARN_UNUSED_VARIABLE = NO;
+				PREBINDING = YES;
+				SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
+				VERSIONING_SYSTEM = "apple-generic";
+			};
+			name = Release;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		48ACD78D0B42848A00D34B4C /* Build configuration list for PBXNativeTarget "Launcher" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				48ACD78E0B42848A00D34B4C /* Debug */,
+				48ACD78F0B42848A00D34B4C /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "Pallet" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				C01FCF4B08A954540054247B /* Debug */,
+				C01FCF4C08A954540054247B /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Pallet" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				C01FCF4F08A954540054247B /* Debug */,
+				C01FCF5008A954540054247B /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
+}

Added: users/rhwood/Pallet/Pallet.xcodeproj/rhwood.mode1
===================================================================
--- users/rhwood/Pallet/Pallet.xcodeproj/rhwood.mode1	                        (rev 0)
+++ users/rhwood/Pallet/Pallet.xcodeproj/rhwood.mode1	2007-03-12 08:51:09 UTC (rev 22706)
@@ -0,0 +1,1377 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>ActivePerspectiveName</key>
+	<string>Project</string>
+	<key>AllowedModules</key>
+	<array>
+		<dict>
+			<key>BundleLoadPath</key>
+			<string></string>
+			<key>MaxInstances</key>
+			<string>n</string>
+			<key>Module</key>
+			<string>PBXSmartGroupTreeModule</string>
+			<key>Name</key>
+			<string>Groups and Files Outline View</string>
+		</dict>
+		<dict>
+			<key>BundleLoadPath</key>
+			<string></string>
+			<key>MaxInstances</key>
+			<string>n</string>
+			<key>Module</key>
+			<string>PBXNavigatorGroup</string>
+			<key>Name</key>
+			<string>Editor</string>
+		</dict>
+		<dict>
+			<key>BundleLoadPath</key>
+			<string></string>
+			<key>MaxInstances</key>
+			<string>n</string>
+			<key>Module</key>
+			<string>XCTaskListModule</string>
+			<key>Name</key>
+			<string>Task List</string>
+		</dict>
+		<dict>
+			<key>BundleLoadPath</key>
+			<string></string>
+			<key>MaxInstances</key>
+			<string>n</string>
+			<key>Module</key>
+			<string>XCDetailModule</string>
+			<key>Name</key>
+			<string>File and Smart Group Detail Viewer</string>
+		</dict>
+		<dict>
+			<key>BundleLoadPath</key>
+			<string></string>
+			<key>MaxInstances</key>
+			<string>1</string>
+			<key>Module</key>
+			<string>PBXBuildResultsModule</string>
+			<key>Name</key>
+			<string>Detailed Build Results Viewer</string>
+		</dict>
+		<dict>
+			<key>BundleLoadPath</key>
+			<string></string>
+			<key>MaxInstances</key>
+			<string>1</string>
+			<key>Module</key>
+			<string>PBXProjectFindModule</string>
+			<key>Name</key>
+			<string>Project Batch Find Tool</string>
+		</dict>
+		<dict>
+			<key>BundleLoadPath</key>
+			<string></string>
+			<key>MaxInstances</key>
+			<string>n</string>
+			<key>Module</key>
+			<string>PBXRunSessionModule</string>
+			<key>Name</key>
+			<string>Run Log</string>
+		</dict>
+		<dict>
+			<key>BundleLoadPath</key>
+			<string></string>
+			<key>MaxInstances</key>
+			<string>n</string>
+			<key>Module</key>
+			<string>PBXBookmarksModule</string>
+			<key>Name</key>
+			<string>Bookmarks Tool</string>
+		</dict>
+		<dict>
+			<key>BundleLoadPath</key>
+			<string></string>
+			<key>MaxInstances</key>
+			<string>n</string>
+			<key>Module</key>
+			<string>PBXClassBrowserModule</string>
+			<key>Name</key>
+			<string>Class Browser</string>
+		</dict>
+		<dict>
+			<key>BundleLoadPath</key>
+			<string></string>
+			<key>MaxInstances</key>
+			<string>n</string>
+			<key>Module</key>
+			<string>PBXCVSModule</string>
+			<key>Name</key>
+			<string>Source Code Control Tool</string>
+		</dict>
+		<dict>
+			<key>BundleLoadPath</key>
+			<string></string>
+			<key>MaxInstances</key>
+			<string>n</string>
+			<key>Module</key>
+			<string>PBXDebugBreakpointsModule</string>
+			<key>Name</key>
+			<string>Debug Breakpoints Tool</string>
+		</dict>
+		<dict>
+			<key>BundleLoadPath</key>
+			<string></string>
+			<key>MaxInstances</key>
+			<string>n</string>
+			<key>Module</key>
+			<string>XCDockableInspector</string>
+			<key>Name</key>
+			<string>Inspector</string>
+		</dict>
+		<dict>
+			<key>BundleLoadPath</key>
+			<string></string>
+			<key>MaxInstances</key>
+			<string>n</string>
+			<key>Module</key>
+			<string>PBXOpenQuicklyModule</string>
+			<key>Name</key>
+			<string>Open Quickly Tool</string>
+		</dict>
+		<dict>
+			<key>BundleLoadPath</key>
+			<string></string>
+			<key>MaxInstances</key>
+			<string>1</string>
+			<key>Module</key>
+			<string>PBXDebugSessionModule</string>
+			<key>Name</key>
+			<string>Debugger</string>
+		</dict>
+		<dict>
+			<key>BundleLoadPath</key>
+			<string></string>
+			<key>MaxInstances</key>
+			<string>1</string>
+			<key>Module</key>
+			<string>PBXDebugCLIModule</string>
+			<key>Name</key>
+			<string>Debug Console</string>
+		</dict>
+	</array>
+	<key>Description</key>
+	<string>DefaultDescriptionKey</string>
+	<key>DockingSystemVisible</key>
+	<false/>
+	<key>Extension</key>
+	<string>mode1</string>
+	<key>FavBarConfig</key>
+	<dict>
+		<key>PBXProjectModuleGUID</key>
+		<string>48D46FD80AD664D700352CE9</string>
+		<key>XCBarModuleItemNames</key>
+		<dict/>
+		<key>XCBarModuleItems</key>
+		<array/>
+	</dict>
+	<key>FirstTimeWindowDisplayed</key>
+	<false/>
+	<key>Identifier</key>
+	<string>com.apple.perspectives.project.mode1</string>
+	<key>MajorVersion</key>
+	<integer>31</integer>
+	<key>MinorVersion</key>
+	<integer>1</integer>
+	<key>Name</key>
+	<string>Default</string>
+	<key>Notifications</key>
+	<array/>
+	<key>OpenEditors</key>
+	<array/>
+	<key>PerspectiveWidths</key>
+	<array>
+		<integer>-1</integer>
+		<integer>-1</integer>
+	</array>
+	<key>Perspectives</key>
+	<array>
+		<dict>
+			<key>ChosenToolbarItems</key>
+			<array>
+				<string>active-target-popup</string>
+				<string>action</string>
+				<string>NSToolbarFlexibleSpaceItem</string>
+				<string>buildOrClean</string>
+				<string>build-and-runOrDebug</string>
+				<string>com.apple.ide.PBXToolbarStopButton</string>
+				<string>get-info</string>
+				<string>toggle-editor</string>
+				<string>NSToolbarFlexibleSpaceItem</string>
+				<string>com.apple.pbx.toolbar.searchfield</string>
+			</array>
+			<key>ControllerClassBaseName</key>
+			<string></string>
+			<key>IconName</key>
+			<string>WindowOfProjectWithEditor</string>
+			<key>Identifier</key>
+			<string>perspective.project</string>
+			<key>IsVertical</key>
+			<false/>
+			<key>Layout</key>
+			<array>
+				<dict>
+					<key>BecomeActive</key>
+					<true/>
+					<key>ContentConfiguration</key>
+					<dict>
+						<key>PBXBottomSmartGroupGIDs</key>
+						<array>
+							<string>1C37FBAC04509CD000000102</string>
+							<string>1C37FAAC04509CD000000102</string>
+							<string>1C08E77C0454961000C914BD</string>
+							<string>1C37FABC05509CD000000102</string>
+							<string>1C37FABC05539CD112110102</string>
+							<string>E2644B35053B69B200211256</string>
+							<string>1C37FABC04509CD000100104</string>
+							<string>1CC0EA4004350EF90044410B</string>
+							<string>1CC0EA4004350EF90041110B</string>
+						</array>
+						<key>PBXProjectModuleGUID</key>
+						<string>1CE0B1FE06471DED0097A5F4</string>
+						<key>PBXProjectModuleLabel</key>
+						<string>Files</string>
+						<key>PBXProjectStructureProvided</key>
+						<string>yes</string>
+						<key>PBXSmartGroupTreeModuleColumnData</key>
+						<dict>
+							<key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+							<array>
+								<real>186</real>
+							</array>
+							<key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+							<array>
+								<string>MainColumn</string>
+							</array>
+						</dict>
+						<key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+						<dict>
+							<key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+							<array>
+								<string>29B97314FDCFA39411CA2CEA</string>
+								<string>080E96DDFE201D6D7F000001</string>
+								<string>29B97315FDCFA39411CA2CEA</string>
+								<string>1C37FBAC04509CD000000102</string>
+								<string>1C37FABC05509CD000000102</string>
+							</array>
+							<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+							<array>
+								<array>
+									<integer>18</integer>
+									<integer>16</integer>
+									<integer>0</integer>
+								</array>
+							</array>
+							<key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+							<string>{{0, 0}, {186, 338}}</string>
+						</dict>
+						<key>PBXTopSmartGroupGIDs</key>
+						<array/>
+						<key>XCIncludePerspectivesSwitch</key>
+						<true/>
+						<key>XCSharingToken</key>
+						<string>com.apple.Xcode.GFSharingToken</string>
+					</dict>
+					<key>GeometryConfiguration</key>
+					<dict>
+						<key>Frame</key>
+						<string>{{0, 0}, {203, 356}}</string>
+						<key>GroupTreeTableConfiguration</key>
+						<array>
+							<string>MainColumn</string>
+							<real>186</real>
+						</array>
+						<key>RubberWindowFrame</key>
+						<string>295 385 690 397 0 0 1280 832 </string>
+					</dict>
+					<key>Module</key>
+					<string>PBXSmartGroupTreeModule</string>
+					<key>Proportion</key>
+					<string>203pt</string>
+				</dict>
+				<dict>
+					<key>Dock</key>
+					<array>
+						<dict>
+							<key>ContentConfiguration</key>
+							<dict>
+								<key>PBXProjectModuleGUID</key>
+								<string>1CE0B20306471E060097A5F4</string>
+								<key>PBXProjectModuleLabel</key>
+								<string></string>
+								<key>PBXSplitModuleInNavigatorKey</key>
+								<dict>
+									<key>Split0</key>
+									<dict>
+										<key>PBXProjectModuleGUID</key>
+										<string>1CE0B20406471E060097A5F4</string>
+										<key>PBXProjectModuleLabel</key>
+										<string></string>
+									</dict>
+									<key>SplitCount</key>
+									<string>1</string>
+								</dict>
+								<key>StatusBarVisibility</key>
+								<true/>
+							</dict>
+							<key>GeometryConfiguration</key>
+							<dict>
+								<key>Frame</key>
+								<string>{{0, 0}, {482, 0}}</string>
+								<key>RubberWindowFrame</key>
+								<string>295 385 690 397 0 0 1280 832 </string>
+							</dict>
+							<key>Module</key>
+							<string>PBXNavigatorGroup</string>
+							<key>Proportion</key>
+							<string>0pt</string>
+						</dict>
+						<dict>
+							<key>ContentConfiguration</key>
+							<dict>
+								<key>PBXProjectModuleGUID</key>
+								<string>1CE0B20506471E060097A5F4</string>
+								<key>PBXProjectModuleLabel</key>
+								<string>Detail</string>
+							</dict>
+							<key>GeometryConfiguration</key>
+							<dict>
+								<key>Frame</key>
+								<string>{{0, 5}, {482, 351}}</string>
+								<key>RubberWindowFrame</key>
+								<string>295 385 690 397 0 0 1280 832 </string>
+							</dict>
+							<key>Module</key>
+							<string>XCDetailModule</string>
+							<key>Proportion</key>
+							<string>351pt</string>
+						</dict>
+					</array>
+					<key>Proportion</key>
+					<string>482pt</string>
+				</dict>
+			</array>
+			<key>Name</key>
+			<string>Project</string>
+			<key>ServiceClasses</key>
+			<array>
+				<string>XCModuleDock</string>
+				<string>PBXSmartGroupTreeModule</string>
+				<string>XCModuleDock</string>
+				<string>PBXNavigatorGroup</string>
+				<string>XCDetailModule</string>
+			</array>
+			<key>TableOfContents</key>
+			<array>
+				<string>48AFB8AC0BA4E0AE00896AF1</string>
+				<string>1CE0B1FE06471DED0097A5F4</string>
+				<string>48AFB8AD0BA4E0AE00896AF1</string>
+				<string>1CE0B20306471E060097A5F4</string>
+				<string>1CE0B20506471E060097A5F4</string>
+			</array>
+			<key>ToolbarConfiguration</key>
+			<string>xcode.toolbar.config.default</string>
+		</dict>
+		<dict>
+			<key>ControllerClassBaseName</key>
+			<string></string>
+			<key>IconName</key>
+			<string>WindowOfProject</string>
+			<key>Identifier</key>
+			<string>perspective.morph</string>
+			<key>IsVertical</key>
+			<integer>0</integer>
+			<key>Layout</key>
+			<array>
+				<dict>
+					<key>BecomeActive</key>
+					<integer>1</integer>
+					<key>ContentConfiguration</key>
+					<dict>
+						<key>PBXBottomSmartGroupGIDs</key>
+						<array>
+							<string>1C37FBAC04509CD000000102</string>
+							<string>1C37FAAC04509CD000000102</string>
+							<string>1C08E77C0454961000C914BD</string>
+							<string>1C37FABC05509CD000000102</string>
+							<string>1C37FABC05539CD112110102</string>
+							<string>E2644B35053B69B200211256</string>
+							<string>1C37FABC04509CD000100104</string>
+							<string>1CC0EA4004350EF90044410B</string>
+							<string>1CC0EA4004350EF90041110B</string>
+						</array>
+						<key>PBXProjectModuleGUID</key>
+						<string>11E0B1FE06471DED0097A5F4</string>
+						<key>PBXProjectModuleLabel</key>
+						<string>Files</string>
+						<key>PBXProjectStructureProvided</key>
+						<string>yes</string>
+						<key>PBXSmartGroupTreeModuleColumnData</key>
+						<dict>
+							<key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+							<array>
+								<real>186</real>
+							</array>
+							<key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+							<array>
+								<string>MainColumn</string>
+							</array>
+						</dict>
+						<key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+						<dict>
+							<key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+							<array>
+								<string>29B97314FDCFA39411CA2CEA</string>
+								<string>1C37FABC05509CD000000102</string>
+							</array>
+							<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+							<array>
+								<array>
+									<integer>0</integer>
+								</array>
+							</array>
+							<key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+							<string>{{0, 0}, {186, 337}}</string>
+						</dict>
+						<key>PBXTopSmartGroupGIDs</key>
+						<array/>
+						<key>XCIncludePerspectivesSwitch</key>
+						<integer>1</integer>
+						<key>XCSharingToken</key>
+						<string>com.apple.Xcode.GFSharingToken</string>
+					</dict>
+					<key>GeometryConfiguration</key>
+					<dict>
+						<key>Frame</key>
+						<string>{{0, 0}, {203, 355}}</string>
+						<key>GroupTreeTableConfiguration</key>
+						<array>
+							<string>MainColumn</string>
+							<real>186</real>
+						</array>
+						<key>RubberWindowFrame</key>
+						<string>373 269 690 397 0 0 1440 878 </string>
+					</dict>
+					<key>Module</key>
+					<string>PBXSmartGroupTreeModule</string>
+					<key>Proportion</key>
+					<string>100%</string>
+				</dict>
+			</array>
+			<key>Name</key>
+			<string>Morph</string>
+			<key>PreferredWidth</key>
+			<integer>300</integer>
+			<key>ServiceClasses</key>
+			<array>
+				<string>XCModuleDock</string>
+				<string>PBXSmartGroupTreeModule</string>
+			</array>
+			<key>TableOfContents</key>
+			<array>
+				<string>11E0B1FE06471DED0097A5F4</string>
+			</array>
+			<key>ToolbarConfiguration</key>
+			<string>xcode.toolbar.config.default.short</string>
+		</dict>
+	</array>
+	<key>PerspectivesBarVisible</key>
+	<false/>
+	<key>ShelfIsVisible</key>
+	<false/>
+	<key>SourceDescription</key>
+	<string>file at '/System/Library/PrivateFrameworks/DevToolsInterface.framework/Versions/A/Resources/XCPerspectivesSpecificationMode1.xcperspec'</string>
+	<key>StatusbarIsVisible</key>
+	<true/>
+	<key>TimeStamp</key>
+	<real>0.0</real>
+	<key>ToolbarDisplayMode</key>
+	<integer>1</integer>
+	<key>ToolbarIsVisible</key>
+	<true/>
+	<key>ToolbarSizeMode</key>
+	<integer>1</integer>
+	<key>Type</key>
+	<string>Perspectives</string>
+	<key>UpdateMessage</key>
+	<string>The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature).  You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature.  Do you wish to update to the latest Workspace defaults for project '%@'?</string>
+	<key>WindowJustification</key>
+	<integer>5</integer>
+	<key>WindowOrderList</key>
+	<array>
+		<string>48D470220AD68BA000352CE9</string>
+		<string>1C0AD2B3069F1EA900FABCE6</string>
+		<string>/Users/rhwood/Developer/Pallet/Pallet.xcodeproj</string>
+	</array>
+	<key>WindowString</key>
+	<string>295 385 690 397 0 0 1280 832 </string>
+	<key>WindowTools</key>
+	<array>
+		<dict>
+			<key>FirstTimeWindowDisplayed</key>
+			<false/>
+			<key>Identifier</key>
+			<string>windowTool.build</string>
+			<key>IsVertical</key>
+			<true/>
+			<key>Layout</key>
+			<array>
+				<dict>
+					<key>Dock</key>
+					<array>
+						<dict>
+							<key>ContentConfiguration</key>
+							<dict>
+								<key>PBXProjectModuleGUID</key>
+								<string>1CD0528F0623707200166675</string>
+								<key>PBXProjectModuleLabel</key>
+								<string></string>
+								<key>StatusBarVisibility</key>
+								<true/>
+							</dict>
+							<key>GeometryConfiguration</key>
+							<dict>
+								<key>Frame</key>
+								<string>{{0, 0}, {615, 218}}</string>
+								<key>RubberWindowFrame</key>
+								<string>591 94 615 500 0 0 1280 832 </string>
+							</dict>
+							<key>Module</key>
+							<string>PBXNavigatorGroup</string>
+							<key>Proportion</key>
+							<string>218pt</string>
+						</dict>
+						<dict>
+							<key>BecomeActive</key>
+							<true/>
+							<key>ContentConfiguration</key>
+							<dict>
+								<key>PBXProjectModuleGUID</key>
+								<string>XCMainBuildResultsModuleGUID</string>
+								<key>PBXProjectModuleLabel</key>
+								<string>Build</string>
+								<key>XCBuildResultsTrigger_Collapse</key>
+								<integer>1021</integer>
+								<key>XCBuildResultsTrigger_Open</key>
+								<integer>1011</integer>
+							</dict>
+							<key>GeometryConfiguration</key>
+							<dict>
+								<key>Frame</key>
+								<string>{{0, 223}, {615, 236}}</string>
+								<key>RubberWindowFrame</key>
+								<string>591 94 615 500 0 0 1280 832 </string>
+							</dict>
+							<key>Module</key>
+							<string>PBXBuildResultsModule</string>
+							<key>Proportion</key>
+							<string>236pt</string>
+						</dict>
+					</array>
+					<key>Proportion</key>
+					<string>459pt</string>
+				</dict>
+			</array>
+			<key>Name</key>
+			<string>Build Results</string>
+			<key>ServiceClasses</key>
+			<array>
+				<string>PBXBuildResultsModule</string>
+			</array>
+			<key>StatusbarIsVisible</key>
+			<true/>
+			<key>TableOfContents</key>
+			<array>
+				<string>48D470220AD68BA000352CE9</string>
+				<string>48AFB8C30BA5487900896AF1</string>
+				<string>1CD0528F0623707200166675</string>
+				<string>XCMainBuildResultsModuleGUID</string>
+			</array>
+			<key>ToolbarConfiguration</key>
+			<string>xcode.toolbar.config.build</string>
+			<key>WindowString</key>
+			<string>591 94 615 500 0 0 1280 832 </string>
+			<key>WindowToolGUID</key>
+			<string>48D470220AD68BA000352CE9</string>
+			<key>WindowToolIsVisible</key>
+			<true/>
+		</dict>
+		<dict>
+			<key>FirstTimeWindowDisplayed</key>
+			<false/>
+			<key>Identifier</key>
+			<string>windowTool.debugger</string>
+			<key>IsVertical</key>
+			<true/>
+			<key>Layout</key>
+			<array>
+				<dict>
+					<key>Dock</key>
+					<array>
+						<dict>
+							<key>ContentConfiguration</key>
+							<dict>
+								<key>Debugger</key>
+								<dict>
+									<key>HorizontalSplitView</key>
+									<dict>
+										<key>_collapsingFrameDimension</key>
+										<real>0.0</real>
+										<key>_indexOfCollapsedView</key>
+										<integer>0</integer>
+										<key>_percentageOfCollapsedView</key>
+										<real>0.0</real>
+										<key>isCollapsed</key>
+										<string>yes</string>
+										<key>sizes</key>
+										<array>
+											<string>{{0, 0}, {272, 200}}</string>
+											<string>{{272, 0}, {422, 200}}</string>
+										</array>
+									</dict>
+									<key>VerticalSplitView</key>
+									<dict>
+										<key>_collapsingFrameDimension</key>
+										<real>0.0</real>
+										<key>_indexOfCollapsedView</key>
+										<integer>0</integer>
+										<key>_percentageOfCollapsedView</key>
+										<real>0.0</real>
+										<key>isCollapsed</key>
+										<string>yes</string>
+										<key>sizes</key>
+										<array>
+											<string>{{0, 0}, {694, 200}}</string>
+											<string>{{0, 200}, {694, 181}}</string>
+										</array>
+									</dict>
+								</dict>
+								<key>LauncherConfigVersion</key>
+								<string>8</string>
+								<key>PBXProjectModuleGUID</key>
+								<string>1C162984064C10D400B95A72</string>
+								<key>PBXProjectModuleLabel</key>
+								<string>Debug - GLUTExamples (Underwater)</string>
+							</dict>
+							<key>GeometryConfiguration</key>
+							<dict>
+								<key>DebugConsoleDrawerSize</key>
+								<string>{100, 120}</string>
+								<key>DebugConsoleVisible</key>
+								<string>None</string>
+								<key>DebugConsoleWindowFrame</key>
+								<string>{{200, 200}, {500, 300}}</string>
+								<key>DebugSTDIOWindowFrame</key>
+								<string>{{200, 200}, {500, 300}}</string>
+								<key>Frame</key>
+								<string>{{0, 0}, {694, 381}}</string>
+								<key>RubberWindowFrame</key>
+								<string>338 392 694 422 0 0 1280 832 </string>
+							</dict>
+							<key>Module</key>
+							<string>PBXDebugSessionModule</string>
+							<key>Proportion</key>
+							<string>381pt</string>
+						</dict>
+					</array>
+					<key>Proportion</key>
+					<string>381pt</string>
+				</dict>
+			</array>
+			<key>Name</key>
+			<string>Debugger</string>
+			<key>ServiceClasses</key>
+			<array>
+				<string>PBXDebugSessionModule</string>
+			</array>
+			<key>StatusbarIsVisible</key>
+			<true/>
+			<key>TableOfContents</key>
+			<array>
+				<string>1CD10A99069EF8BA00B06720</string>
+				<string>488483D90BA460A700427E1F</string>
+				<string>1C162984064C10D400B95A72</string>
+				<string>488483DA0BA460A700427E1F</string>
+				<string>488483DB0BA460A700427E1F</string>
+				<string>488483DC0BA460A700427E1F</string>
+				<string>488483DD0BA460A700427E1F</string>
+				<string>488483DE0BA460A700427E1F</string>
+				<string>488483DF0BA460A700427E1F</string>
+			</array>
+			<key>ToolbarConfiguration</key>
+			<string>xcode.toolbar.config.debug</string>
+			<key>WindowString</key>
+			<string>338 392 694 422 0 0 1280 832 </string>
+			<key>WindowToolGUID</key>
+			<string>1CD10A99069EF8BA00B06720</string>
+			<key>WindowToolIsVisible</key>
+			<false/>
+		</dict>
+		<dict>
+			<key>FirstTimeWindowDisplayed</key>
+			<false/>
+			<key>Identifier</key>
+			<string>windowTool.find</string>
+			<key>IsVertical</key>
+			<true/>
+			<key>Layout</key>
+			<array>
+				<dict>
+					<key>Dock</key>
+					<array>
+						<dict>
+							<key>Dock</key>
+							<array>
+								<dict>
+									<key>ContentConfiguration</key>
+									<dict>
+										<key>PBXProjectModuleGUID</key>
+										<string>1CDD528C0622207200134675</string>
+										<key>PBXProjectModuleLabel</key>
+										<string>Info.plist</string>
+										<key>StatusBarVisibility</key>
+										<true/>
+									</dict>
+									<key>GeometryConfiguration</key>
+									<dict>
+										<key>Frame</key>
+										<string>{{0, 0}, {781, 212}}</string>
+										<key>RubberWindowFrame</key>
+										<string>387 238 781 470 0 0 1280 832 </string>
+									</dict>
+									<key>Module</key>
+									<string>PBXNavigatorGroup</string>
+									<key>Proportion</key>
+									<string>781pt</string>
+								</dict>
+							</array>
+							<key>Proportion</key>
+							<string>212pt</string>
+						</dict>
+						<dict>
+							<key>BecomeActive</key>
+							<true/>
+							<key>ContentConfiguration</key>
+							<dict>
+								<key>PBXProjectModuleGUID</key>
+								<string>1CD0528E0623707200166675</string>
+								<key>PBXProjectModuleLabel</key>
+								<string>Project Find</string>
+							</dict>
+							<key>GeometryConfiguration</key>
+							<dict>
+								<key>Frame</key>
+								<string>{{0, 217}, {781, 212}}</string>
+								<key>RubberWindowFrame</key>
+								<string>387 238 781 470 0 0 1280 832 </string>
+							</dict>
+							<key>Module</key>
+							<string>PBXProjectFindModule</string>
+							<key>Proportion</key>
+							<string>212pt</string>
+						</dict>
+					</array>
+					<key>Proportion</key>
+					<string>429pt</string>
+				</dict>
+			</array>
+			<key>Name</key>
+			<string>Project Find</string>
+			<key>ServiceClasses</key>
+			<array>
+				<string>PBXProjectFindModule</string>
+			</array>
+			<key>StatusbarIsVisible</key>
+			<true/>
+			<key>TableOfContents</key>
+			<array>
+				<string>1C530D57069F1CE1000CFCEE</string>
+				<string>488483FF0BA465E900427E1F</string>
+				<string>488484000BA465E900427E1F</string>
+				<string>1CDD528C0622207200134675</string>
+				<string>1CD0528E0623707200166675</string>
+			</array>
+			<key>WindowString</key>
+			<string>387 238 781 470 0 0 1280 832 </string>
+			<key>WindowToolGUID</key>
+			<string>1C530D57069F1CE1000CFCEE</string>
+			<key>WindowToolIsVisible</key>
+			<false/>
+		</dict>
+		<dict>
+			<key>Identifier</key>
+			<string>MENUSEPARATOR</string>
+		</dict>
+		<dict>
+			<key>FirstTimeWindowDisplayed</key>
+			<false/>
+			<key>Identifier</key>
+			<string>windowTool.debuggerConsole</string>
+			<key>IsVertical</key>
+			<true/>
+			<key>Layout</key>
+			<array>
+				<dict>
+					<key>Dock</key>
+					<array>
+						<dict>
+							<key>ContentConfiguration</key>
+							<dict>
+								<key>PBXProjectModuleGUID</key>
+								<string>1C78EAAC065D492600B07095</string>
+								<key>PBXProjectModuleLabel</key>
+								<string>Debugger Console</string>
+							</dict>
+							<key>GeometryConfiguration</key>
+							<dict>
+								<key>Frame</key>
+								<string>{{0, 0}, {440, 358}}</string>
+								<key>RubberWindowFrame</key>
+								<string>358 313 440 400 0 0 1280 832 </string>
+							</dict>
+							<key>Module</key>
+							<string>PBXDebugCLIModule</string>
+							<key>Proportion</key>
+							<string>358pt</string>
+						</dict>
+					</array>
+					<key>Proportion</key>
+					<string>359pt</string>
+				</dict>
+			</array>
+			<key>Name</key>
+			<string>Debugger Console</string>
+			<key>ServiceClasses</key>
+			<array>
+				<string>PBXDebugCLIModule</string>
+			</array>
+			<key>StatusbarIsVisible</key>
+			<true/>
+			<key>TableOfContents</key>
+			<array>
+				<string>48D470EE0AD739F900352CE9</string>
+				<string>4884840E0BA490C400427E1F</string>
+				<string>1C78EAAC065D492600B07095</string>
+			</array>
+			<key>WindowString</key>
+			<string>358 313 440 400 0 0 1280 832 </string>
+			<key>WindowToolGUID</key>
+			<string>48D470EE0AD739F900352CE9</string>
+			<key>WindowToolIsVisible</key>
+			<false/>
+		</dict>
+		<dict>
+			<key>FirstTimeWindowDisplayed</key>
+			<false/>
+			<key>Identifier</key>
+			<string>windowTool.run</string>
+			<key>IsVertical</key>
+			<true/>
+			<key>Layout</key>
+			<array>
+				<dict>
+					<key>Dock</key>
+					<array>
+						<dict>
+							<key>ContentConfiguration</key>
+							<dict>
+								<key>LauncherConfigVersion</key>
+								<string>3</string>
+								<key>PBXProjectModuleGUID</key>
+								<string>1CD0528B0623707200166675</string>
+								<key>PBXProjectModuleLabel</key>
+								<string>Run</string>
+								<key>Runner</key>
+								<dict>
+									<key>HorizontalSplitView</key>
+									<dict>
+										<key>_collapsingFrameDimension</key>
+										<real>0.0</real>
+										<key>_indexOfCollapsedView</key>
+										<integer>0</integer>
+										<key>_percentageOfCollapsedView</key>
+										<real>0.0</real>
+										<key>isCollapsed</key>
+										<string>yes</string>
+										<key>sizes</key>
+										<array>
+											<string>{{0, 0}, {493, 167}}</string>
+											<string>{{0, 176}, {493, 267}}</string>
+										</array>
+									</dict>
+									<key>VerticalSplitView</key>
+									<dict>
+										<key>_collapsingFrameDimension</key>
+										<real>0.0</real>
+										<key>_indexOfCollapsedView</key>
+										<integer>0</integer>
+										<key>_percentageOfCollapsedView</key>
+										<real>0.0</real>
+										<key>isCollapsed</key>
+										<string>yes</string>
+										<key>sizes</key>
+										<array>
+											<string>{{0, 0}, {405, 443}}</string>
+											<string>{{414, 0}, {514, 443}}</string>
+										</array>
+									</dict>
+								</dict>
+							</dict>
+							<key>GeometryConfiguration</key>
+							<dict>
+								<key>Frame</key>
+								<string>{{0, 0}, {500, 425}}</string>
+								<key>RubberWindowFrame</key>
+								<string>720 352 500 466 0 0 1280 832 </string>
+							</dict>
+							<key>Module</key>
+							<string>PBXRunSessionModule</string>
+							<key>Proportion</key>
+							<string>425pt</string>
+						</dict>
+					</array>
+					<key>Proportion</key>
+					<string>425pt</string>
+				</dict>
+			</array>
+			<key>Name</key>
+			<string>Run Log</string>
+			<key>ServiceClasses</key>
+			<array>
+				<string>PBXRunSessionModule</string>
+			</array>
+			<key>StatusbarIsVisible</key>
+			<true/>
+			<key>TableOfContents</key>
+			<array>
+				<string>1C0AD2B3069F1EA900FABCE6</string>
+				<string>48AFB8AF0BA4E0AE00896AF1</string>
+				<string>1CD0528B0623707200166675</string>
+				<string>48AFB8B00BA4E0AE00896AF1</string>
+			</array>
+			<key>ToolbarConfiguration</key>
+			<string>xcode.toolbar.config.run</string>
+			<key>WindowString</key>
+			<string>720 352 500 466 0 0 1280 832 </string>
+			<key>WindowToolGUID</key>
+			<string>1C0AD2B3069F1EA900FABCE6</string>
+			<key>WindowToolIsVisible</key>
+			<true/>
+		</dict>
+		<dict>
+			<key>Identifier</key>
+			<string>windowTool.scm</string>
+			<key>Layout</key>
+			<array>
+				<dict>
+					<key>Dock</key>
+					<array>
+						<dict>
+							<key>ContentConfiguration</key>
+							<dict>
+								<key>PBXProjectModuleGUID</key>
+								<string>1C78EAB2065D492600B07095</string>
+								<key>PBXProjectModuleLabel</key>
+								<string>&lt;No Editor&gt;</string>
+								<key>PBXSplitModuleInNavigatorKey</key>
+								<dict>
+									<key>Split0</key>
+									<dict>
+										<key>PBXProjectModuleGUID</key>
+										<string>1C78EAB3065D492600B07095</string>
+									</dict>
+									<key>SplitCount</key>
+									<string>1</string>
+								</dict>
+								<key>StatusBarVisibility</key>
+								<integer>1</integer>
+							</dict>
+							<key>GeometryConfiguration</key>
+							<dict>
+								<key>Frame</key>
+								<string>{{0, 0}, {452, 0}}</string>
+								<key>RubberWindowFrame</key>
+								<string>743 379 452 308 0 0 1280 1002 </string>
+							</dict>
+							<key>Module</key>
+							<string>PBXNavigatorGroup</string>
+							<key>Proportion</key>
+							<string>0pt</string>
+						</dict>
+						<dict>
+							<key>BecomeActive</key>
+							<integer>1</integer>
+							<key>ContentConfiguration</key>
+							<dict>
+								<key>PBXProjectModuleGUID</key>
+								<string>1CD052920623707200166675</string>
+								<key>PBXProjectModuleLabel</key>
+								<string>SCM</string>
+							</dict>
+							<key>GeometryConfiguration</key>
+							<dict>
+								<key>ConsoleFrame</key>
+								<string>{{0, 259}, {452, 0}}</string>
+								<key>Frame</key>
+								<string>{{0, 7}, {452, 259}}</string>
+								<key>RubberWindowFrame</key>
+								<string>743 379 452 308 0 0 1280 1002 </string>
+								<key>TableConfiguration</key>
+								<array>
+									<string>Status</string>
+									<real>30</real>
+									<string>FileName</string>
+									<real>199</real>
+									<string>Path</string>
+									<real>197.09500122070312</real>
+								</array>
+								<key>TableFrame</key>
+								<string>{{0, 0}, {452, 250}}</string>
+							</dict>
+							<key>Module</key>
+							<string>PBXCVSModule</string>
+							<key>Proportion</key>
+							<string>262pt</string>
+						</dict>
+					</array>
+					<key>Proportion</key>
+					<string>266pt</string>
+				</dict>
+			</array>
+			<key>Name</key>
+			<string>SCM</string>
+			<key>ServiceClasses</key>
+			<array>
+				<string>PBXCVSModule</string>
+			</array>
+			<key>StatusbarIsVisible</key>
+			<integer>1</integer>
+			<key>TableOfContents</key>
+			<array>
+				<string>1C78EAB4065D492600B07095</string>
+				<string>1C78EAB5065D492600B07095</string>
+				<string>1C78EAB2065D492600B07095</string>
+				<string>1CD052920623707200166675</string>
+			</array>
+			<key>ToolbarConfiguration</key>
+			<string>xcode.toolbar.config.scm</string>
+			<key>WindowString</key>
+			<string>743 379 452 308 0 0 1280 1002 </string>
+		</dict>
+		<dict>
+			<key>FirstTimeWindowDisplayed</key>
+			<false/>
+			<key>Identifier</key>
+			<string>windowTool.breakpoints</string>
+			<key>IsVertical</key>
+			<false/>
+			<key>Layout</key>
+			<array>
+				<dict>
+					<key>Dock</key>
+					<array>
+						<dict>
+							<key>ContentConfiguration</key>
+							<dict>
+								<key>PBXBottomSmartGroupGIDs</key>
+								<array>
+									<string>1C77FABC04509CD000000102</string>
+								</array>
+								<key>PBXProjectModuleGUID</key>
+								<string>1CE0B1FE06471DED0097A5F4</string>
+								<key>PBXProjectModuleLabel</key>
+								<string>Files</string>
+								<key>PBXProjectStructureProvided</key>
+								<string>no</string>
+								<key>PBXSmartGroupTreeModuleColumnData</key>
+								<dict>
+									<key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+									<array>
+										<real>168</real>
+									</array>
+									<key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+									<array>
+										<string>MainColumn</string>
+									</array>
+								</dict>
+								<key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+								<dict>
+									<key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+									<array>
+										<string>1C77FABC04509CD000000102</string>
+									</array>
+									<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+									<array>
+										<array>
+											<integer>0</integer>
+										</array>
+									</array>
+									<key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+									<string>{{0, 0}, {168, 350}}</string>
+								</dict>
+								<key>PBXTopSmartGroupGIDs</key>
+								<array/>
+								<key>XCIncludePerspectivesSwitch</key>
+								<false/>
+							</dict>
+							<key>GeometryConfiguration</key>
+							<dict>
+								<key>Frame</key>
+								<string>{{0, 0}, {185, 368}}</string>
+								<key>GroupTreeTableConfiguration</key>
+								<array>
+									<string>MainColumn</string>
+									<real>168</real>
+								</array>
+								<key>RubberWindowFrame</key>
+								<string>36 400 744 409 0 0 1280 832 </string>
+							</dict>
+							<key>Module</key>
+							<string>PBXSmartGroupTreeModule</string>
+							<key>Proportion</key>
+							<string>185pt</string>
+						</dict>
+						<dict>
+							<key>BecomeActive</key>
+							<true/>
+							<key>ContentConfiguration</key>
+							<dict>
+								<key>PBXProjectModuleGUID</key>
+								<string>1CA1AED706398EBD00589147</string>
+								<key>PBXProjectModuleLabel</key>
+								<string>Detail</string>
+							</dict>
+							<key>GeometryConfiguration</key>
+							<dict>
+								<key>Frame</key>
+								<string>{{190, 0}, {554, 368}}</string>
+								<key>RubberWindowFrame</key>
+								<string>36 400 744 409 0 0 1280 832 </string>
+							</dict>
+							<key>Module</key>
+							<string>XCDetailModule</string>
+							<key>Proportion</key>
+							<string>554pt</string>
+						</dict>
+					</array>
+					<key>Proportion</key>
+					<string>368pt</string>
+				</dict>
+			</array>
+			<key>MajorVersion</key>
+			<integer>2</integer>
+			<key>MinorVersion</key>
+			<integer>0</integer>
+			<key>Name</key>
+			<string>Breakpoints</string>
+			<key>ServiceClasses</key>
+			<array>
+				<string>PBXSmartGroupTreeModule</string>
+				<string>XCDetailModule</string>
+			</array>
+			<key>StatusbarIsVisible</key>
+			<true/>
+			<key>TableOfContents</key>
+			<array>
+				<string>484FAF750B4AFE540089893C</string>
+				<string>484FAF760B4AFE540089893C</string>
+				<string>1CE0B1FE06471DED0097A5F4</string>
+				<string>1CA1AED706398EBD00589147</string>
+			</array>
+			<key>ToolbarConfiguration</key>
+			<string>xcode.toolbar.config.breakpoints</string>
+			<key>WindowString</key>
+			<string>36 400 744 409 0 0 1280 832 </string>
+			<key>WindowToolGUID</key>
+			<string>484FAF750B4AFE540089893C</string>
+			<key>WindowToolIsVisible</key>
+			<false/>
+		</dict>
+		<dict>
+			<key>FirstTimeWindowDisplayed</key>
+			<false/>
+			<key>Identifier</key>
+			<string>windowTool.debugAnimator</string>
+			<key>IsVertical</key>
+			<true/>
+			<key>Layout</key>
+			<array>
+				<dict>
+					<key>Dock</key>
+					<array>
+						<dict>
+							<key>BecomeActive</key>
+							<true/>
+							<key>ContentConfiguration</key>
+							<dict>
+								<key>PBXProjectModuleGUID</key>
+								<string>48D471290AD73A9200352CE9</string>
+								<key>PBXProjectModuleLabel</key>
+								<string></string>
+								<key>StatusBarVisibility</key>
+								<true/>
+							</dict>
+							<key>GeometryConfiguration</key>
+							<dict>
+								<key>Frame</key>
+								<string>{{0, 0}, {700, 459}}</string>
+								<key>RubberWindowFrame</key>
+								<string>379 190 700 500 0 0 1280 832 </string>
+							</dict>
+							<key>Module</key>
+							<string>PBXNavigatorGroup</string>
+							<key>Proportion</key>
+							<string>459pt</string>
+						</dict>
+					</array>
+					<key>Proportion</key>
+					<string>459pt</string>
+				</dict>
+			</array>
+			<key>Name</key>
+			<string>Debug Visualizer</string>
+			<key>ServiceClasses</key>
+			<array>
+				<string>PBXNavigatorGroup</string>
+			</array>
+			<key>StatusbarIsVisible</key>
+			<true/>
+			<key>TableOfContents</key>
+			<array>
+				<string>485B6BF20B512D3900FA812C</string>
+				<string>485B6BF30B512D3900FA812C</string>
+				<string>48D471290AD73A9200352CE9</string>
+			</array>
+			<key>ToolbarConfiguration</key>
+			<string>xcode.toolbar.config.debugAnimator</string>
+			<key>WindowString</key>
+			<string>379 190 700 500 0 0 1280 832 </string>
+			<key>WindowToolGUID</key>
+			<string>485B6BF20B512D3900FA812C</string>
+			<key>WindowToolIsVisible</key>
+			<false/>
+		</dict>
+		<dict>
+			<key>Identifier</key>
+			<string>windowTool.bookmarks</string>
+			<key>Layout</key>
+			<array>
+				<dict>
+					<key>Dock</key>
+					<array>
+						<dict>
+							<key>Module</key>
+							<string>PBXBookmarksModule</string>
+							<key>Proportion</key>
+							<string>100%</string>
+						</dict>
+					</array>
+					<key>Proportion</key>
+					<string>100%</string>
+				</dict>
+			</array>
+			<key>Name</key>
+			<string>Bookmarks</string>
+			<key>ServiceClasses</key>
+			<array>
+				<string>PBXBookmarksModule</string>
+			</array>
+			<key>StatusbarIsVisible</key>
+			<integer>0</integer>
+			<key>WindowString</key>
+			<string>538 42 401 187 0 0 1280 1002 </string>
+		</dict>
+		<dict>
+			<key>Identifier</key>
+			<string>windowTool.classBrowser</string>
+			<key>Layout</key>
+			<array>
+				<dict>
+					<key>Dock</key>
+					<array>
+						<dict>
+							<key>BecomeActive</key>
+							<integer>1</integer>
+							<key>ContentConfiguration</key>
+							<dict>
+								<key>OptionsSetName</key>
+								<string>Hierarchy, all classes</string>
+								<key>PBXProjectModuleGUID</key>
+								<string>1CA6456E063B45B4001379D8</string>
+								<key>PBXProjectModuleLabel</key>
+								<string>Class Browser - NSObject</string>
+							</dict>
+							<key>GeometryConfiguration</key>
+							<dict>
+								<key>ClassesFrame</key>
+								<string>{{0, 0}, {374, 96}}</string>
+								<key>ClassesTreeTableConfiguration</key>
+								<array>
+									<string>PBXClassNameColumnIdentifier</string>
+									<real>208</real>
+									<string>PBXClassBookColumnIdentifier</string>
+									<real>22</real>
+								</array>
+								<key>Frame</key>
+								<string>{{0, 0}, {630, 331}}</string>
+								<key>MembersFrame</key>
+								<string>{{0, 105}, {374, 395}}</string>
+								<key>MembersTreeTableConfiguration</key>
+								<array>
+									<string>PBXMemberTypeIconColumnIdentifier</string>
+									<real>22</real>
+									<string>PBXMemberNameColumnIdentifier</string>
+									<real>216</real>
+									<string>PBXMemberTypeColumnIdentifier</string>
+									<real>97</real>
+									<string>PBXMemberBookColumnIdentifier</string>
+									<real>22</real>
+								</array>
+								<key>PBXModuleWindowStatusBarHidden2</key>
+								<integer>1</integer>
+								<key>RubberWindowFrame</key>
+								<string>385 179 630 352 0 0 1440 878 </string>
+							</dict>
+							<key>Module</key>
+							<string>PBXClassBrowserModule</string>
+							<key>Proportion</key>
+							<string>332pt</string>
+						</dict>
+					</array>
+					<key>Proportion</key>
+					<string>332pt</string>
+				</dict>
+			</array>
+			<key>Name</key>
+			<string>Class Browser</string>
+			<key>ServiceClasses</key>
+			<array>
+				<string>PBXClassBrowserModule</string>
+			</array>
+			<key>StatusbarIsVisible</key>
+			<integer>0</integer>
+			<key>TableOfContents</key>
+			<array>
+				<string>1C0AD2AF069F1E9B00FABCE6</string>
+				<string>1C0AD2B0069F1E9B00FABCE6</string>
+				<string>1CA6456E063B45B4001379D8</string>
+			</array>
+			<key>ToolbarConfiguration</key>
+			<string>xcode.toolbar.config.classbrowser</string>
+			<key>WindowString</key>
+			<string>385 179 630 352 0 0 1440 878 </string>
+			<key>WindowToolGUID</key>
+			<string>1C0AD2AF069F1E9B00FABCE6</string>
+			<key>WindowToolIsVisible</key>
+			<integer>0</integer>
+		</dict>
+	</array>
+</dict>
+</plist>

Added: users/rhwood/Pallet/Pallet.xcodeproj/rhwood.pbxuser
===================================================================
--- users/rhwood/Pallet/Pallet.xcodeproj/rhwood.pbxuser	                        (rev 0)
+++ users/rhwood/Pallet/Pallet.xcodeproj/rhwood.pbxuser	2007-03-12 08:51:09 UTC (rev 22706)
@@ -0,0 +1,498 @@
+// !$*UTF8*$!
+{
+	089C165DFE840E0CC02AAC07 /* English */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {711, 699}}";
+			sepNavSelRange = "{109, 0}";
+			sepNavVisRect = "{{0, 0}, {711, 699}}";
+			sepNavWindowFrame = "{{176, -4}, {750, 828}}";
+		};
+	};
+	29B97313FDCFA39411CA2CEA /* Project object */ = {
+		activeBuildConfigurationName = Debug;
+		activeExecutable = 48D46FCA0AD664C700352CE9 /* Pallet */;
+		activeTarget = 8D1107260486CEB800E47090 /* Pallet */;
+		addToTargets = (
+		);
+		breakpoints = (
+		);
+		breakpointsGroup = 48D470D60AD72A6D00352CE9 /* XCBreakpointsBucket */;
+		codeSenseManager = 48D46FDA0AD664D800352CE9 /* Code sense */;
+		executables = (
+			48D46FCA0AD664C700352CE9 /* Pallet */,
+			48ACD78C0B42846B00D34B4C /* Launcher */,
+		);
+		perUserDictionary = {
+			"PBXConfiguration.PBXBreakpointsDataSource.v1:1CA1AED706398EBD00589147" = {
+				PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+				PBXFileTableDataSourceColumnSortingKey = PBXBreakpointsDataSource_BreakpointID;
+				PBXFileTableDataSourceColumnWidthsKey = (
+					20,
+					20,
+					210,
+					20,
+					110,
+					109,
+					20,
+				);
+				PBXFileTableDataSourceColumnsKey = (
+					PBXBreakpointsDataSource_ActionID,
+					PBXBreakpointsDataSource_TypeID,
+					PBXBreakpointsDataSource_BreakpointID,
+					PBXBreakpointsDataSource_UseID,
+					PBXBreakpointsDataSource_LocationID,
+					PBXBreakpointsDataSource_ConditionID,
+					PBXBreakpointsDataSource_ContinueID,
+				);
+			};
+			PBXConfiguration.PBXFileTableDataSource3.PBXExecutablesDataSource = {
+				PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+				PBXFileTableDataSourceColumnSortingKey = PBXExecutablesDataSource_NameID;
+				PBXFileTableDataSourceColumnWidthsKey = (
+					22,
+					300,
+					131,
+				);
+				PBXFileTableDataSourceColumnsKey = (
+					PBXExecutablesDataSource_ActiveFlagID,
+					PBXExecutablesDataSource_NameID,
+					PBXExecutablesDataSource_CommentsID,
+				);
+			};
+			PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = {
+				PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+				PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
+				PBXFileTableDataSourceColumnWidthsKey = (
+					20,
+					243,
+					20,
+					48,
+					43,
+					43,
+					20,
+				);
+				PBXFileTableDataSourceColumnsKey = (
+					PBXFileDataSource_FiletypeID,
+					PBXFileDataSource_Filename_ColumnID,
+					PBXFileDataSource_Built_ColumnID,
+					PBXFileDataSource_ObjectSize_ColumnID,
+					PBXFileDataSource_Errors_ColumnID,
+					PBXFileDataSource_Warnings_ColumnID,
+					PBXFileDataSource_Target_ColumnID,
+				);
+			};
+			PBXConfiguration.PBXFileTableDataSource3.PBXFindDataSource = {
+				PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+				PBXFileTableDataSourceColumnSortingKey = PBXFindDataSource_LocationID;
+				PBXFileTableDataSourceColumnWidthsKey = (
+					200,
+					120,
+				);
+				PBXFileTableDataSourceColumnsKey = (
+					PBXFindDataSource_MessageID,
+					PBXFindDataSource_LocationID,
+				);
+			};
+			PBXConfiguration.PBXFileTableDataSource3.XCSCMDataSource = {
+				PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+				PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
+				PBXFileTableDataSourceColumnWidthsKey = (
+					20,
+					20,
+					219,
+					20,
+					48.1626,
+					43,
+					43,
+					20,
+				);
+				PBXFileTableDataSourceColumnsKey = (
+					PBXFileDataSource_SCM_ColumnID,
+					PBXFileDataSource_FiletypeID,
+					PBXFileDataSource_Filename_ColumnID,
+					PBXFileDataSource_Built_ColumnID,
+					PBXFileDataSource_ObjectSize_ColumnID,
+					PBXFileDataSource_Errors_ColumnID,
+					PBXFileDataSource_Warnings_ColumnID,
+					PBXFileDataSource_Target_ColumnID,
+				);
+			};
+			PBXConfiguration.PBXTargetDataSource.PBXTargetDataSource = {
+				PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+				PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
+				PBXFileTableDataSourceColumnWidthsKey = (
+					20,
+					200,
+					63,
+					20,
+					48,
+					43,
+					43,
+				);
+				PBXFileTableDataSourceColumnsKey = (
+					PBXFileDataSource_FiletypeID,
+					PBXFileDataSource_Filename_ColumnID,
+					PBXTargetDataSource_PrimaryAttribute,
+					PBXFileDataSource_Built_ColumnID,
+					PBXFileDataSource_ObjectSize_ColumnID,
+					PBXFileDataSource_Errors_ColumnID,
+					PBXFileDataSource_Warnings_ColumnID,
+				);
+			};
+			PBXPerProjectTemplateStateSaveDate = 195354773;
+			PBXWorkspaceStateSaveDate = 195354773;
+		};
+		sourceControlManager = 48D46FD90AD664D800352CE9 /* Source Control */;
+		userBuildSettings = {
+		};
+	};
+	29B97316FDCFA39411CA2CEA /* main.m */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {740, 210}}";
+			sepNavSelRange = "{24, 0}";
+			sepNavVisRect = "{{0, 0}, {740, 180}}";
+			sepNavWindowFrame = "{{15, 3}, {750, 828}}";
+		};
+	};
+	32CA4F630368D1EE00C91783 /* Port Authority_Prefix.pch */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {740, 238}}";
+			sepNavSelRange = "{78, 0}";
+			sepNavVisRect = "{{0, 0}, {740, 180}}";
+			sepNavWindowFrame = "{{363, -26}, {750, 828}}";
+		};
+	};
+	4800621E0B58FB31005F27E4 /* MPPort.m */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {614, 364}}";
+			sepNavSelRange = "{371, 5}";
+			sepNavVisRect = "{{0, 166}, {574, 186}}";
+			sepNavWindowFrame = "{{426, 4}, {750, 828}}";
+		};
+	};
+	4800621F0B58FB31005F27E4 /* MPPort.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {711, 699}}";
+			sepNavSelRange = "{81, 0}";
+			sepNavVisRect = "{{0, 0}, {711, 699}}";
+			sepNavWindowFrame = "{{15, 4}, {750, 828}}";
+		};
+	};
+	480062BD0B597D9A005F27E4 /* PAStatusTransformer.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {740, 336}}";
+			sepNavSelRange = "{39, 0}";
+			sepNavVisRect = "{{0, 0}, {740, 180}}";
+		};
+	};
+	480062BE0B597D9A005F27E4 /* PAStatusTransformer.m */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {740, 644}}";
+			sepNavSelRange = "{39, 0}";
+			sepNavVisRect = "{{0, 0}, {740, 180}}";
+			sepNavWindowFrame = "{{15, -1}, {750, 828}}";
+		};
+	};
+	4828C62F0AD7B84D002AF0DD /* TaskWrapper.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {2492, 1176}}";
+			sepNavSelRange = "{458, 1}";
+			sepNavVisRect = "{{0, 477}, {711, 699}}";
+			sepNavWindowFrame = "{{15, -1}, {750, 828}}";
+		};
+	};
+	4828C6300AD7B84D002AF0DD /* TaskWrapper.m */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {2132, 2324}}";
+			sepNavSelRange = "{6684, 0}";
+			sepNavVisRect = "{{0, 921}, {711, 699}}";
+			sepNavWindowFrame = "{{15, -1}, {750, 828}}";
+		};
+	};
+	483A5E440B57A50900712840 /* MPPortsController.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {711, 699}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRect = "{{0, 0}, {711, 699}}";
+			sepNavWindowFrame = "{{15, -1}, {750, 828}}";
+		};
+	};
+	483A5E450B57A50900712840 /* MPPortsController.m */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {866, 699}}";
+			sepNavSelRange = "{1199, 0}";
+			sepNavVisRect = "{{29, 0}, {711, 699}}";
+			sepNavWindowFrame = "{{15, 4}, {750, 828}}";
+		};
+	};
+	4844B92A0AD91F5800A4A4DB /* UserDefaults.plist */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {711, 699}}";
+			sepNavSelRange = "{232, 0}";
+			sepNavVisRect = "{{0, 0}, {711, 699}}";
+			sepNavWindowFrame = "{{15, -1}, {750, 828}}";
+		};
+	};
+	4854CE6A0B42107000950EE4 /* Launcher_Prefix.pch */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {711, 699}}";
+			sepNavSelRange = "{80, 0}";
+			sepNavVisRect = "{{0, 0}, {711, 699}}";
+			sepNavWindowFrame = "{{15, 4}, {750, 828}}";
+		};
+	};
+	487EB9470B453785001B0F72 /* AuthorizedExecutable.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {711, 1554}}";
+			sepNavSelRange = "{2225, 0}";
+			sepNavVisRect = "{{0, 0}, {711, 699}}";
+			sepNavWindowFrame = "{{434, 4}, {750, 828}}";
+		};
+	};
+	487EB9480B453786001B0F72 /* AuthorizedExecutable.m */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1556, 7014}}";
+			sepNavSelRange = "{678, 0}";
+			sepNavVisRect = "{{0, 0}, {711, 699}}";
+			sepNavWindowFrame = "{{15, 4}, {750, 828}}";
+		};
+	};
+	48ACD78A0B42846B00D34B4C /* Launcher */ = {
+		activeExec = 0;
+		executables = (
+			48ACD78C0B42846B00D34B4C /* Launcher */,
+		);
+	};
+	48ACD78C0B42846B00D34B4C /* Launcher */ = {
+		isa = PBXExecutable;
+		activeArgIndex = 2147483647;
+		activeArgIndices = (
+		);
+		argumentStrings = (
+		);
+		autoAttachOnCrash = 1;
+		configStateDict = {
+		};
+		customDataFormattersEnabled = 1;
+		debuggerPlugin = GDBDebugging;
+		disassemblyDisplayState = 0;
+		dylibVariantSuffix = "";
+		enableDebugStr = 1;
+		environmentEntries = (
+		);
+		executableSystemSymbolLevel = 0;
+		executableUserSymbolLevel = 0;
+		libgmallocEnabled = 0;
+		name = Launcher;
+		sourceDirectories = (
+		);
+	};
+	48ACD7D10B42855600D34B4C /* Launcher.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {711, 699}}";
+			sepNavSelRange = "{1540, 0}";
+			sepNavVisRect = "{{0, 0}, {711, 699}}";
+			sepNavWindowFrame = "{{491, 4}, {750, 828}}";
+		};
+	};
+	48ACD7D20B42855600D34B4C /* Launcher.m */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1976, 1960}}";
+			sepNavSelRange = "{28, 0}";
+			sepNavVisRect = "{{0, 0}, {740, 180}}";
+			sepNavWindowFrame = "{{15, 4}, {750, 828}}";
+		};
+	};
+	48AFB8B70BA4E20300896AF1 /* Debug.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {796, 698}}";
+			sepNavSelRange = "{195, 0}";
+			sepNavVisRect = "{{0, 0}, {796, 698}}";
+			sepNavWindowFrame = "{{15, 0}, {835, 827}}";
+		};
+	};
+	48BBCE7D0B41B2450063A19F /* Launcher.c */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1106, 5544}}";
+			sepNavSelRange = "{9292, 0}";
+			sepNavVisRect = "{{0, 2756}, {711, 699}}";
+			sepNavWindowFrame = "{{491, 4}, {750, 828}}";
+		};
+	};
+	48BBCE870B41B37F0063A19F /* getpath.c */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {836, 2408}}";
+			sepNavSelRange = "{5809, 56}";
+			sepNavVisRect = "{{0, 1916}, {574, 186}}";
+			sepNavWindowFrame = "{{15, 4}, {750, 828}}";
+		};
+	};
+	48D46FCA0AD664C700352CE9 /* Pallet */ = {
+		isa = PBXExecutable;
+		activeArgIndex = 0;
+		activeArgIndices = (
+			YES,
+		);
+		argumentStrings = (
+			"-NSBindingDebugLogLevel 1",
+		);
+		autoAttachOnCrash = 1;
+		configStateDict = {
+		};
+		customDataFormattersEnabled = 1;
+		debuggerPlugin = GDBDebugging;
+		disassemblyDisplayState = 0;
+		dylibVariantSuffix = "";
+		enableDebugStr = 1;
+		environmentEntries = (
+		);
+		executableSystemSymbolLevel = 0;
+		executableUserSymbolLevel = 0;
+		libgmallocEnabled = 0;
+		name = Pallet;
+		savedGlobals = {
+		};
+		sourceDirectories = (
+		);
+		variableFormatDictionary = {
+			$cr = 1;
+			$ctr = 1;
+			$lr = 1;
+			$mq = 1;
+			$pc = 1;
+			$ps = 1;
+			$r0 = 1;
+			$r1 = 1;
+			$r10 = 1;
+			$r11 = 1;
+			$r12 = 1;
+			$r13 = 1;
+			$r14 = 1;
+			$r15 = 1;
+			$r16 = 1;
+			$r17 = 1;
+			$r18 = 1;
+			$r19 = 1;
+			$r2 = 1;
+			$r20 = 1;
+			$r21 = 1;
+			$r22 = 1;
+			$r23 = 1;
+			$r24 = 1;
+			$r25 = 1;
+			$r26 = 1;
+			$r27 = 1;
+			$r28 = 1;
+			$r29 = 1;
+			$r3 = 1;
+			$r30 = 1;
+			$r31 = 1;
+			$r4 = 1;
+			$r5 = 1;
+			$r6 = 1;
+			$r7 = 1;
+			$r8 = 1;
+			$r9 = 1;
+			$v0 = 1;
+			$v1 = 1;
+			$v10 = 1;
+			$v11 = 1;
+			$v12 = 1;
+			$v13 = 1;
+			$v14 = 1;
+			$v15 = 1;
+			$v16 = 1;
+			$v17 = 1;
+			$v18 = 1;
+			$v19 = 1;
+			$v2 = 1;
+			$v20 = 1;
+			$v21 = 1;
+			$v22 = 1;
+			$v23 = 1;
+			$v24 = 1;
+			$v25 = 1;
+			$v26 = 1;
+			$v27 = 1;
+			$v28 = 1;
+			$v29 = 1;
+			$v3 = 1;
+			$v30 = 1;
+			$v31 = 1;
+			$v4 = 1;
+			$v5 = 1;
+			$v6 = 1;
+			$v7 = 1;
+			$v8 = 1;
+			$v9 = 1;
+			$vrsave = 1;
+			$vscr = 1;
+			$xer = 1;
+		};
+	};
+	48D46FD90AD664D800352CE9 /* Source Control */ = {
+		isa = PBXSourceControlManager;
+		fallbackIsa = XCSourceControlManager;
+		isSCMEnabled = 1;
+		scmConfiguration = {
+			SubversionToolPath = /opt/local/bin/svn;
+		};
+		scmType = scm.subversion;
+	};
+	48D46FDA0AD664D800352CE9 /* Code sense */ = {
+		isa = PBXCodeSenseManager;
+		indexTemplatePath = "";
+	};
+	48D470170AD6867B00352CE9 /* PortAuthority.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {740, 1274}}";
+			sepNavSelRange = "{31, 6}";
+			sepNavVisRect = "{{0, 0}, {740, 180}}";
+			sepNavWindowFrame = "{{15, 4}, {750, 828}}";
+		};
+	};
+	48D470180AD6867C00352CE9 /* PortAuthority.m */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1058, 7378}}";
+			sepNavSelRange = "{6914, 0}";
+			sepNavVisRect = "{{0, 2380}, {796, 698}}";
+			sepNavWindowFrame = "{{50, 5}, {835, 827}}";
+		};
+	};
+	48D470770AD6CFFB00352CE9 /* MPToolbar.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {824, 910}}";
+			sepNavSelRange = "{35, 0}";
+			sepNavVisRect = "{{0, 0}, {740, 180}}";
+			sepNavWindowFrame = "{{103, 4}, {750, 828}}";
+		};
+	};
+	48D470780AD6CFFB00352CE9 /* MPToolbar.m */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {818, 3080}}";
+			sepNavSelRange = "{35, 0}";
+			sepNavVisRect = "{{0, 0}, {740, 180}}";
+			sepNavWindowFrame = "{{166, 4}, {750, 828}}";
+		};
+	};
+	48D470D60AD72A6D00352CE9 /* XCBreakpointsBucket */ = {
+		isa = XCBreakpointsBucket;
+		name = "Port Authority";
+		objects = (
+		);
+	};
+	8D1107260486CEB800E47090 /* Pallet */ = {
+		activeExec = 0;
+		executables = (
+			48D46FCA0AD664C700352CE9 /* Pallet */,
+		);
+	};
+	8D1107310486CEB800E47090 /* Info.plist */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {740, 462}}";
+			sepNavSelRange = "{290, 0}";
+			sepNavVisRect = "{{0, 15}, {740, 180}}";
+			sepNavWindowFrame = "{{353, 4}, {750, 828}}";
+		};
+	};
+}

Added: users/rhwood/Pallet/Port Authority_Prefix.pch
===================================================================
--- users/rhwood/Pallet/Port Authority_Prefix.pch	                        (rev 0)
+++ users/rhwood/Pallet/Port Authority_Prefix.pch	2007-03-12 08:51:09 UTC (rev 22706)
@@ -0,0 +1,17 @@
+//
+// Prefix header for all source files of the 'Pallet' target in the 'Pallet' project
+//
+
+#ifdef __OBJC__
+	#import <AppKit/AppKit.h>
+	#import <Cocoa/Cocoa.h>
+	#import <Foundation/Foundation.h>
+	#import <Security/Authorization.h>
+	#import <Security/AuthorizationTags.h>
+#endif
+
+/*
+#ifndef PORT_PREFIX
+	#define PORT_PREFIX /opt/local
+#endif
+ */
\ No newline at end of file

Added: users/rhwood/Pallet/PortAuthority.h
===================================================================
--- users/rhwood/Pallet/PortAuthority.h	                        (rev 0)
+++ users/rhwood/Pallet/PortAuthority.h	2007-03-12 08:51:09 UTC (rev 22706)
@@ -0,0 +1,90 @@
+/*
+	Class MPAuthority
+	Project Pallet
+
+	Copyright (C) 2006 MacPorts.
+ 
+	This code is free software; you can redistribute it and/or modify it under
+	the terms of the GNU General Public License as published by the Free
+	Software Foundation; either version 2 of the License, or any later version.
+ 
+	This code is distributed in the hope that it will be useful, but WITHOUT ANY
+	WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+	FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+	details.
+ 
+	For a copy of the GNU General Public License, visit <http://www.gnu.org/> or
+	write to the Free Software Foundation, Inc., 59 Temple Place--Suite 330,
+	Boston, MA 02111-1307, USA.
+
+	More information is available at http://www.macports.org or macports-users at lists.macosforge.org
+ 
+	History:
+	
+	Created by Randall Wood rhwood at macports.org on 6 October 2006
+ */
+
+#import <Cocoa/Cocoa.h>
+#import "MPPortsController.h"
+#import "MPPort.h"
+#import "PAStatusTransformer.h"
+#import "TaskWrapper.h"
+#import "AuthorizedExecutable.h"
+
+ at interface PortAuthority : NSObject <TaskWrapperController>
+
+{
+    IBOutlet NSTableView *portsList;
+    IBOutlet NSTextView *portInfo;
+    IBOutlet NSProgressIndicator *progressIndicator;
+    IBOutlet NSTextField *status;
+	IBOutlet NSTextView *portLog;
+	IBOutlet NSWindow *portsWindow;
+	IBOutlet NSWindow *portLogWindow;
+	IBOutlet MPPortsController *portIndexController;
+	
+//	IBOutlet NSTextField *portInstallationPath; // this needs to be set correctly first run to ensure that
+												// the preference gets stored
+
+	NSMutableArray *portIndex;
+	
+	NSMutableArray *taskQueue;
+	BOOL portIsRunning;
+	TaskWrapper *portTask;
+	int portCommand;
+	NSString *lastOutput;
+	NSString *launcher;
+	NSString *macPortsPath;
+	NSString *macPortsPort;
+	AuthorizedExecutable *authPortTask;
+	AuthorizedExecutable *killTask;
+
+	NSDictionary *portIndexes;
+
+}
+- (IBAction)installPort:(id)sender;
+- (IBAction)reinstallPort:(id)sender;
+- (IBAction)removePort:(id)sender;
+- (IBAction)syncPortsList:(id)sender;
+- (IBAction)updateMacPorts:(id)sender;
+- (IBAction)upgradeOutdated:(id)sender;
+- (IBAction)upgradePort:(id)sender;
+- (IBAction)haltPortCommand:(id)sender;
+
+- (void)runPortCommand:(NSString *)action port:(NSString *)port;
+- (void)runPortCommandInThread:(id)parameters;
+
+- (IBAction)about:(id)sender;
+- (IBAction)macPortsSite:(id)sender;
+- (IBAction)portAuthoritySite:(id)sender;
+
+- (void)getPortIndexes;
+- (NSString *)pathToPortIndexWithSource:(NSString *)source;
+- (void)populatePortIndex;
+
+- (void)launchExecutableWithArguments:(NSMutableArray *)args;
+- (void)launchAuthorizedExecutableWithArguments:(NSMutableArray *)args;
+
+- (void)parsePortIndex:(NSString *)portIndex intoIndexObject:(id)indexObject;
+
+ at end

Added: users/rhwood/Pallet/PortAuthority.m
===================================================================
--- users/rhwood/Pallet/PortAuthority.m	                        (rev 0)
+++ users/rhwood/Pallet/PortAuthority.m	2007-03-12 08:51:09 UTC (rev 22706)
@@ -0,0 +1,526 @@
+/*
+	Class MPAuthority
+	Project Pallet
+ 
+	Copyright (C) 2006 MacPorts.
+ 
+	This code is free software; you can redistribute it and/or modify it under
+	the terms of the GNU General Public License as published by the Free
+	Software Foundation; either version 2 of the License, or any later version.
+ 
+	This code is distributed in the hope that it will be useful, but WITHOUT ANY
+	WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+	FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+	details.
+ 
+	For a copy of the GNU General Public License, visit <http://www.gnu.org/> or
+	write to the Free Software Foundation, Inc., 59 Temple Place--Suite 330,
+	Boston, MA 02111-1307, USA.
+ 
+	More information is available at http://www.macports.org or macports-users at lists.macosforge.org
+ 
+	History:
+	
+	Created by Randall Wood rhwood at macports.org on 6 October 2006
+ */
+
+#import "PortAuthority.h"
+
+#include <tcl.h>
+
+ at implementation PortAuthority
+
+enum portCommands {
+	portList,
+	portListAll,
+	portSync,
+	portSelfupdate,
+	portListInstalled,
+	portListOutdated
+};
+
+#pragma mark STARTUP
+
+- (void)awakeFromNib
+{
+	// Load/set preferences/defaults
+	if (![[[NSUserDefaultsController sharedUserDefaultsController] values] valueForKey:@"portInstallationPath"]) {
+		[[[NSUserDefaultsController sharedUserDefaultsController] values] setValue:@"/opt/local" forKey:@"portInstallationPath"];
+		NSString *userDefaultsValuesPath;
+		NSDictionary *userDefaultsValuesDict;
+		userDefaultsValuesPath = [[NSBundle mainBundle] pathForResource:@"UserDefaults" 
+																 ofType:@"plist"];
+		userDefaultsValuesDict = [NSDictionary dictionaryWithContentsOfFile:userDefaultsValuesPath];
+		[[NSUserDefaults standardUserDefaults] registerDefaults:userDefaultsValuesDict];
+		[[NSUserDefaultsController sharedUserDefaultsController] setInitialValues:userDefaultsValuesDict];
+	}
+	// Hide duplicate items in Windows menu
+	[portsWindow setExcludedFromWindowsMenu:YES];
+	[portLogWindow setExcludedFromWindowsMenu:YES];
+	// Locate port
+	macPortsPath = [[[NSUserDefaultsController sharedUserDefaultsController] values] valueForKey:@"portInstallationPath"];
+	macPortsPort = [[NSString alloc] initWithString:[macPortsPath stringByAppendingPathComponent:@"bin/port"]];
+	// Clean the main window
+	[status setStringValue:@""];
+	// Setup the port task
+	portIsRunning = NO;
+	launcher = [[NSBundle mainBundle] pathForResource:@"Launcher" ofType:nil];
+	authPortTask = [[AuthorizedExecutable alloc] initWithExecutable:launcher];
+	killTask = [[AuthorizedExecutable alloc] initWithExecutable:launcher];
+	[authPortTask setDelegate:self];
+	[killTask setDelegate:self];
+	// Setup the value transformers used in bindings
+	NSValueTransformer *transformer = [[PAStatusTransformer alloc] init];
+	[NSValueTransformer setValueTransformer:transformer forName:@"PAStatusTransformer"];
+}
+
+/*
+	TODO: rewrite to run sync/selfupdate, and port list methods in thread so as not to block UI.
+ */
+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
+{
+	// sync or selfupdate as required
+	if ([[[[NSUserDefaultsController sharedUserDefaultsController] values] valueForKey:@"updateMacPortsOnStartup"] boolValue] == YES) {
+		[self updateMacPorts:nil];
+	} else if ([[[[NSUserDefaultsController sharedUserDefaultsController] values] valueForKey:@"synchronizePortsListOnStartup"] boolValue] == YES) {
+		[self syncPortsList:nil];
+	}
+	// List ports
+	[self getPortIndexes];
+	[self populatePortIndex];
+}
+
+#pragma mark PORT INDEX
+
+- (void)getPortIndexes
+{
+	NSArray *conf;
+	NSString *path;
+	NSString *file;
+	NSMutableDictionary *sources;
+	NSEnumerator *enumerator;
+	id line;
+	NSMutableString *source;
+
+	source = [[NSMutableString alloc] init];
+	sources = [[NSMutableDictionary alloc] init];
+	path = [macPortsPath stringByAppendingPathComponent:@"etc/ports/sources.conf"];
+	file = [[NSString alloc] initWithContentsOfFile:path];
+	conf = [[NSArray alloc] initWithArray:[file componentsSeparatedByString:@"\n"]];
+	if ([conf count] == 1) {
+		[conf release];
+		conf = [[NSArray alloc] initWithArray:[file componentsSeparatedByString:@"\r"]];
+	}
+	enumerator = [conf objectEnumerator];
+	while (line = [enumerator nextObject]) {
+		@try {
+			if ([line characterAtIndex:0] != '#') {
+				[sources setValue:[self pathToPortIndexWithSource:line] forKey:line];
+			}
+		}
+		@catch (NSException *exception) {
+			// Exceptions will be thrown where line is nil or 0 length
+			// Ignore the exception since it means only that the line was empty
+		}
+	}
+	if (portIndexes != nil) {
+		[portIndexes release];
+	}
+	portIndexes = [[NSDictionary alloc] initWithDictionary:sources copyItems:YES];
+}
+
+- (NSString *)pathToPortIndexWithSource:(NSString *)source
+{
+	NSMutableString *path;
+	path = [[NSMutableString alloc] init];
+	if ([[source substringToIndex:4] isEqualToString:@"file"]) {
+		[path setString:[source substringFromIndex:7]];
+	} else if ([[source substringToIndex:5] isEqualToString:@"rsync"]) {
+		[path setString:source];
+		[path replaceOccurrencesOfString:@"/" withString:@"_" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [path length])];
+		[path replaceOccurrencesOfString:@":__" withString:@"." options:NSCaseInsensitiveSearch range:NSMakeRange(0, [path length])];
+		[path setString:[[macPortsPath stringByAppendingPathComponent:@"var/db/dports/sources"] stringByAppendingPathComponent:path]];
+	}
+	return [path stringByAppendingPathComponent:@"PortIndex"];
+}
+
+- (void)parsePortIndex:(NSString *)index intoIndexObject:(id)indexObject
+{
+	NSString *file;
+	NSArray *lines;
+	NSMutableArray *arrays;
+	NSMutableDictionary *port;
+	NSArray *array;
+	NSEnumerator *indexEnumerator;
+	int counter;
+	int tclCount;
+	int tclResult;
+	const char **tclElements;
+	NSStringEncoding encoding;
+	NSString *key;
+	NSString *value;
+	id line;
+	arrays = [[NSMutableArray alloc] init];
+	file = [[NSString alloc] initWithContentsOfFile:index];
+	lines = [file componentsSeparatedByString:@"\n"];
+	indexEnumerator = [lines objectEnumerator];
+	while (line = [indexEnumerator nextObject]) {
+		array = [line componentsSeparatedByString:@" "];
+		if ([array count] > 2) {
+			[arrays addObject:line];
+		}
+	}
+	indexEnumerator = [arrays objectEnumerator];
+	while (line = [indexEnumerator nextObject]) {
+		port = [[NSMutableDictionary alloc] init];
+		tclResult = Tcl_SplitList(NULL, [line cString], &tclCount, &tclElements);
+		if (tclResult == TCL_OK && !(tclCount % 2)) {
+			encoding = [NSString defaultCStringEncoding];
+			for (counter = 0; counter < tclCount; counter+=2) {
+				key = [[NSString alloc] initWithCString:tclElements[counter] encoding:encoding];
+				value = [[NSString alloc] initWithCString:tclElements[counter + 1] encoding:encoding];
+				[port setValue:value forKey:key];
+				//NSLog(@"%@: %@\n", key, value);
+			}
+			NSLog(@"\n\nparsing %@\n\n", [port valueForKey:@"name"]);
+			if ([[port valueForKey:@"long_description"] characterAtIndex:0] == '{') {
+				NSLog(@"\n\nchanging %@\n\n", [port valueForKey:@"name"]);
+				[port setValue:[port valueForKey:@"description"] forKey:@"long_description"];
+			}
+			// generate a composite version string: version_revision
+			[port setValue:[[[port valueForKey:@"version"] stringByAppendingString:@"_"] stringByAppendingString:[port valueForKey:@"revision"]] forKey:@"compositeVersion"];
+			// set the status flag to unknown
+			[port setValue:[NSNumber numberWithInt:portStatusUnknown] forKey:@"status"];
+			[indexObject addObject:port];
+		} else {
+			NSLog(@"Line \"%@\" from index %@ is bad.\n", line, index);
+		}
+	}
+	//NSLog(@"Parsed %d ports from index %@\n", [ports count], index);
+	Tcl_Free((char *)tclElements);
+}
+
+- (void)populatePortIndex
+{
+	NSEnumerator *indexEnumerator;
+	id index;
+	if (portIndex = nil) {
+		portIndex = [[NSMutableArray alloc] init];
+	}
+	indexEnumerator = [portIndexes keyEnumerator];
+	while (index = [indexEnumerator nextObject]) {
+		[progressIndicator startAnimation:nil];
+		[status setStringValue:@"Listing ports in all indexes..."];
+		[status setStringValue:[NSString stringWithFormat:
+			NSLocalizedStringWithDefaultValue(@"statusPopulatePortIndex",
+											  @"Localizable",
+											  [NSBundle mainBundle],
+											  @"Listing ports in index %@",
+											  @"Status for [MPAuthority populatePortIndex] method"),
+			index]];
+		[self parsePortIndex:[portIndexes valueForKey:index] intoIndexObject:portIndexController];
+	}
+	[status setStringValue:@""];
+	[progressIndicator stopAnimation:nil];
+}
+
+- (void)indexPortsInThread
+{
+	
+}
+
+#pragma mark PORT COMMANDS
+
+- (void)defaultAction:(id)items
+{
+	id item;
+	NSEnumerator *itemsEnumerator;
+	switch ([[item valueForKey:@"status"] intValue]) {
+		case portStatusActive:
+			[self launchAuthorizedExecutableWithArguments:[NSArray arrayWithObjects:macPortsPort,
+				@"uninstall",
+				@"-dv",
+				[item valueForKey:@"name"]]];
+			break;
+		case portStatusInstalled:
+			[self launchAuthorizedExecutableWithArguments:[NSArray arrayWithObjects:macPortsPort,
+				@"activate",
+				@"-dv",
+				[item valueForKey:@"name"]]];
+			break;
+		case portStatusOutdated:
+			[self launchAuthorizedExecutableWithArguments:[NSArray arrayWithObjects:macPortsPort,
+				@"upgrade",
+				@"-dv",
+				[item valueForKey:@"name"]]];
+			break;
+		case portStatusUnknown:
+			[self launchAuthorizedExecutableWithArguments:[NSArray arrayWithObjects:macPortsPort,
+				@"install",
+				@"-dv",
+				[item valueForKey:@"name"]]];
+			break;
+		default:
+			break;
+	}
+}
+
+- (IBAction)installPort:(id)sender
+{
+}
+
+- (IBAction)reinstallPort:(id)sender
+{
+}
+
+- (IBAction)removePort:(id)sender
+{
+}
+
+- (IBAction)syncPortsList:(id)sender
+{
+	if (!portIsRunning) {
+		portCommand = portSync;
+		[status setStringValue:NSLocalizedStringWithDefaultValue(@"statusSyncPortsList",
+																 @"Localizable",
+																 [NSBundle mainBundle],
+																 @"Syncing ports list with MacPorts",
+																 @"Status for [MPAuthority syncPortsList] method")]; 
+		[self launchAuthorizedExecutableWithArguments:[NSArray arrayWithObjects:macPortsPort,
+			@"sync",
+			nil]];
+	}
+}
+
+- (IBAction)updateMacPorts:(id)sender
+{
+	if (!portIsRunning) {
+		portCommand = portSelfupdate;
+		[status setStringValue:NSLocalizedStringWithDefaultValue(@"statusUpdateMacPorts",
+																 @"Localizable",
+																 [NSBundle mainBundle],
+																 @"Updating MacPorts Installation",
+																 @"Status for [MPAuthority updateMacPorts] method")]; 
+		[self launchAuthorizedExecutableWithArguments:[NSArray arrayWithObjects:macPortsPort,
+			@"selfupdate",
+			nil]];
+	}
+}
+
+- (IBAction)upgradeOutdated:(id)sender
+{
+}
+
+- (IBAction)upgradePort:(id)sender
+{
+}
+
+- (IBAction)haltPortCommand:(id)sender
+{
+	
+}
+
+- (void)runPortCommand:(NSString *)action port:(NSString *)port
+{
+	
+}
+
+
+
+- (void)runPortCommandInThread:(id)parameters
+{
+	
+}
+
+#pragma mark TABLES
+
+- (void)updateAvailablePorts:(id)output
+{
+	NSMutableArray *fields;
+	NSMutableDictionary *columns;
+	columns = [[NSMutableDictionary alloc] initWithCapacity:4];
+	fields = [[NSMutableArray alloc] initWithArray:[output componentsSeparatedByString:@" "]];
+	[fields removeObjectIdenticalTo:[NSString string]];
+	[columns setValue:[NSNumber numberWithInt:portStatusUnknown] forKey:@"status"];
+	[columns setValue:[fields objectAtIndex:0] forKey:@"name"];
+	[columns setValue:[fields objectAtIndex:1] forKey:@"version"];
+	[columns setValue:[fields objectAtIndex:2] forKey:@"categories"];
+	[portIndex addObject:columns];
+	[portsList reloadData];
+}
+
+#pragma mark TABLE DATASOURCES
+
+- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
+{
+	NSLog(@"request for row %@ column %@\n", [NSNumber numberWithInt:rowIndex], [aTableColumn identifier]);
+	NSParameterAssert(rowIndex >= 0 && rowIndex < [portIndex count]);
+	if ([[[aTableColumn identifier] stringValue] isEqualToString:@"status"]) {
+		switch ([[[portIndex objectAtIndex:rowIndex] objectForKey:[aTableColumn identifier]] intValue]) {
+			case portStatusInstalled:
+				return nil;
+				break;
+			case portStatusActive:
+				return nil;
+				break;
+			case portStatusOutdated:
+				return nil;
+				break;
+			default:
+				return nil;
+		}
+	}
+	return [[portIndex objectAtIndex:rowIndex] objectForKey:[aTableColumn identifier]];
+}
+
+- (int)numberOfRowsInTableView:(NSTableView *)aTableView
+{
+	return [portIndex count];
+}
+
+#pragma mark MENU ITEMS
+
+- (IBAction)about:(id)sender
+{
+	NSMutableDictionary *options;
+	NSMutableAttributedString *credits;
+	NSMutableString *version;
+	
+	version = [NSMutableString stringWithContentsOfFile:[macPortsPath stringByAppendingPathComponent:@"etc/ports/dp_version"]];
+	[version deleteCharactersInRange:NSMakeRange([version length] - 1, 1)];
+	credits = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:
+		NSLocalizedStringFromTable(@"MacPorts Version: %@",
+								   @"Localizable",
+								   @"MacPorts Version"),
+		version]];
+	
+	[credits setAlignment:NSCenterTextAlignment range:NSMakeRange(0, [credits length])];
+	[credits addAttribute:@"NSFontAttributeName" value:[NSFont labelFontOfSize:[NSFont labelFontSize]] range:NSMakeRange(0, [credits length])];
+	options = [[NSMutableDictionary alloc] init];
+	[options setObject:credits forKey:@"Credits"];
+	[NSApp orderFrontStandardAboutPanelWithOptions:options];
+}
+
+- (IBAction)macPortsSite:(id)sender
+{
+	[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://www.macports.org"]];
+}
+
+- (IBAction)portAuthoritySite:(id)sender
+{
+	[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://www.macports.org"]];
+}
+
+#pragma mark UTILITIES
+
+- (void)launchExecutableWithArguments:(NSMutableArray *)args
+{
+	if (!portIsRunning) {
+		portIsRunning = YES;
+		[NSApp setApplicationIconImage:[NSImage imageNamed:@"ApplicationIconBusy"]];
+		if (portTask != nil) {
+			[portTask release];
+		}
+		portTask = [[TaskWrapper alloc] initWithController:self arguments:args];
+		[portTask startProcess];
+	}
+}
+
+- (void)launchAuthorizedExecutableWithArguments:(NSMutableArray *)args
+{
+	if (!portIsRunning) {
+		portIsRunning = YES;
+		[NSApp setApplicationIconImage:[NSImage imageNamed:@"ApplicationIconBusy"]];
+		[authPortTask setArguments:args];
+		[authPortTask authorizeWithQuery];
+		[authPortTask start];
+	} else {
+		[taskQueue addObject:args];
+	}
+}
+
+#pragma mark TOOLBAR
+
+- (BOOL)validateToolbarItem:(NSToolbarItem *)theItem
+{
+	return YES;
+}
+
+#pragma mark AUTHORIZED EXECUTABLE DELEGATES / TASK WRAPPER CONTROLLER
+// This callback is implemented as part of conforming to the ProcessController protocol.
+// It will be called whenever there is output from the TaskWrapper.
+- (void)appendOutput:(NSString *)output
+{
+    // add the string (a chunk of the results from locate) to the NSTextView's
+    // backing store, in the form of an attributed string
+    [[portLog textStorage] appendAttributedString: [[[NSAttributedString alloc]
+                             initWithString: output] autorelease]];
+    // setup a selector to be called the next time through the event loop to scroll
+    // the view to the just pasted text.  We don't want to scroll right now,
+    // because of a bug in Mac OS X version 10.1 that causes scrolling in the context
+    // of a text storage update to starve the app of events
+    [self performSelector:@selector(scrollToVisible:) withObject:nil afterDelay:0.0];
+	switch (portCommand) {
+	}
+}
+
+// This routine is called after adding new results to the text view's backing store.
+// We now need to scroll the NSScrollView in which the NSTextView sits to the part
+// that we just added at the end
+- (void)scrollToVisible:(id)ignore {
+    [portLog scrollRangeToVisible:NSMakeRange([[portLog string] length], 0)];
+}
+
+// A callback that gets called when a TaskWrapper is launched, allowing us to do any setup
+// that is needed from the app side.  This method is implemented as a part of conforming
+// to the ProcessController protocol.
+- (void)processStarted
+{
+    portIsRunning = YES;
+    [portLog setString:@""];
+	[progressIndicator startAnimation:nil];
+}
+
+// A callback that gets called when a TaskWrapper is completed, allowing us to do any cleanup
+// that is needed from the app side.  This method is implemented as a part of conforming
+// to the ProcessController protocol.
+- (void)processFinished
+{
+    portIsRunning = NO;
+	[status setStringValue:@""];
+	[progressIndicator stopAnimation:nil];
+	if ([taskQueue count]) {
+		[self launchAuthorizedExecutableWithArguments:[taskQueue objectAtIndex:0]];
+		[taskQueue removeObjectAtIndex:0];
+	}
+}
+
+- (void)captureOutput:(NSString*)str forExecutable:(AuthorizedExecutable*)exe
+{
+    [[portLog textStorage] appendAttributedString: [[[NSAttributedString alloc]
+                             initWithString: str] autorelease]];
+    [self performSelector:@selector(scrollToVisible:) withObject:nil afterDelay:0.0];
+}
+
+- (void)executableFinished:(AuthorizedExecutable *)exe withStatus:(int)exeStatus
+{
+	portIsRunning = NO;
+	[status setStringValue:@""];
+	[progressIndicator stopAnimation:nil];
+	if ([taskQueue count]) {
+		[self launchAuthorizedExecutableWithArguments:[taskQueue objectAtIndex:0]];
+		[taskQueue removeObjectAtIndex:0];
+	}
+}
+
+#pragma mark APPLICATION DELEGATES
+
+-(void)applicationWillTerminate:(NSNotification*)anotification
+{
+	[NSApp setApplicationIconImage:[NSImage imageNamed:@"ApplicationIcon"]];
+    [authPortTask unAuthorize];
+	[killTask unAuthorize];
+}
+
+
+ at end

Added: users/rhwood/Pallet/Remove.tiff
===================================================================
(Binary files differ)


Property changes on: users/rhwood/Pallet/Remove.tiff
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: users/rhwood/Pallet/Sync.tiff
===================================================================
(Binary files differ)


Property changes on: users/rhwood/Pallet/Sync.tiff
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: users/rhwood/Pallet/TaskWrapper.h
===================================================================
--- users/rhwood/Pallet/TaskWrapper.h	                        (rev 0)
+++ users/rhwood/Pallet/TaskWrapper.h	2007-03-12 08:51:09 UTC (rev 22706)
@@ -0,0 +1,83 @@


More information about the macports-changes mailing list