/**
  * Answers all available programs in the operating system. Note that a <code>Display</code> must
  * already exist to guarantee that this method returns an appropriate result.
  *
  * @return an array of programs
  */
 public static Program[] getPrograms() {
   NSAutoreleasePool pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
   try {
     List<Program> vector = new ArrayList<>();
     NSWorkspace workspace = NSWorkspace.sharedWorkspace();
     NSArray array =
         new NSArray(
             OS.NSSearchPathForDirectoriesInDomains(
                 OS.NSAllApplicationsDirectory, OS.NSAllDomainsMask, true));
     int count = (int) /*64*/ array.count();
     for (int i = 0; i < count; i++) {
       NSString path = new NSString(array.objectAtIndex(i));
       NSFileManager fileManager = NSFileManager.defaultManager();
       NSDirectoryEnumerator enumerator = fileManager.enumeratorAtPath(path);
       if (enumerator != null) {
         id id;
         while ((id = enumerator.nextObject()) != null) {
           enumerator.skipDescendents();
           NSString fullPath = path.stringByAppendingPathComponent(new NSString(id.id));
           if (workspace.isFilePackageAtPath(fullPath)) {
             NSBundle bundle = NSBundle.bundleWithPath(fullPath);
             if (bundle != null) {
               Program program = getProgram(bundle);
               if (program != null) vector.add(program);
             }
           }
         }
       }
     }
     return vector.toArray(new Program[vector.size()]);
   } finally {
     pool.release();
   }
 }
 static boolean isExecutable(String fileName) {
   long /*int*/ ptr = OS.malloc(1);
   NSString path = NSString.stringWith(fileName);
   boolean result = false;
   NSFileManager manager = NSFileManager.defaultManager();
   if (manager.fileExistsAtPath(path, ptr)) {
     byte[] isDirectory = new byte[1];
     OS.memmove(isDirectory, ptr, 1);
     if (isDirectory[0] == 0 && manager.isExecutableFileAtPath(path)) {
       NSWorkspace ws = NSWorkspace.sharedWorkspace();
       NSString type = ws.typeOfFile(path, 0);
       result =
           type != null
               && (ws.type(type, NSString.stringWith("public.unix-executable"))
                   || //$NON-NLS-1$
                   OS.UTTypeEqual(
                       type.id, NSString.stringWith("public.shell-script").id)); // $NON-NLS-1$
     }
   }
   OS.free(ptr);
   return result;
 }
 static NSURL getURL(String fileName) {
   NSString unescapedStr;
   String lowercaseName = fileName.toLowerCase();
   if (lowercaseName.startsWith(PREFIX_HTTP)
       || lowercaseName.startsWith(PREFIX_HTTPS)
       || lowercaseName.startsWith(PREFIX_FILE)) {
     unescapedStr = NSString.stringWith("%#"); // $NON-NLS-1$
   } else {
     unescapedStr = NSString.stringWith("%"); // $NON-NLS-1$
   }
   NSString fullPath = NSString.stringWith(fileName);
   if (NSFileManager.defaultManager().fileExistsAtPath(fullPath)) {
     fullPath = NSURL.fileURLWithPath(fullPath).absoluteString();
   }
   long /*int*/ ptr =
       OS.CFURLCreateStringByAddingPercentEscapes(
           0, fullPath.id, unescapedStr.id, 0, OS.kCFStringEncodingUTF8);
   NSString escapedString = new NSString(ptr);
   NSURL url = NSURL.URLWithString(escapedString);
   OS.CFRelease(ptr);
   return url;
 }
 /**
  * Answer all program extensions in the operating system. Note that a <code>Display</code> must
  * already exist to guarantee that this method returns an appropriate result.
  *
  * @return an array of extensions
  */
 public static String[] getExtensions() {
   NSAutoreleasePool pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
   try {
     NSMutableSet supportedDocumentTypes = (NSMutableSet) NSMutableSet.set();
     NSWorkspace workspace = NSWorkspace.sharedWorkspace();
     NSString CFBundleDocumentTypes = NSString.stringWith("CFBundleDocumentTypes");
     NSString CFBundleTypeExtensions = NSString.stringWith("CFBundleTypeExtensions");
     NSArray array =
         new NSArray(
             OS.NSSearchPathForDirectoriesInDomains(
                 OS.NSAllApplicationsDirectory, OS.NSAllDomainsMask, true));
     int count = (int) /*64*/ array.count();
     for (int i = 0; i < count; i++) {
       NSString path = new NSString(array.objectAtIndex(i));
       NSFileManager fileManager = NSFileManager.defaultManager();
       NSDirectoryEnumerator enumerator = fileManager.enumeratorAtPath(path);
       if (enumerator != null) {
         id id;
         while ((id = enumerator.nextObject()) != null) {
           enumerator.skipDescendents();
           NSString filePath = new NSString(id.id);
           NSString fullPath = path.stringByAppendingPathComponent(filePath);
           if (workspace.isFilePackageAtPath(fullPath)) {
             NSBundle bundle = NSBundle.bundleWithPath(fullPath);
             id =
                 bundle != null
                     ? bundle.infoDictionary().objectForKey(CFBundleDocumentTypes)
                     : null;
             if (id != null) {
               NSDictionary documentTypes = new NSDictionary(id.id);
               NSEnumerator documentTypesEnumerator = documentTypes.objectEnumerator();
               while ((id = documentTypesEnumerator.nextObject()) != null) {
                 NSDictionary documentType = new NSDictionary(id.id);
                 id = documentType.objectForKey(CFBundleTypeExtensions);
                 if (id != null) {
                   supportedDocumentTypes.addObjectsFromArray(new NSArray(id.id));
                 }
               }
             }
           }
         }
       }
     }
     int i = 0;
     String[] exts = new String[(int) /*64*/ supportedDocumentTypes.count()];
     NSEnumerator enumerator = supportedDocumentTypes.objectEnumerator();
     id id;
     while ((id = enumerator.nextObject()) != null) {
       String ext = new NSString(id.id).getString();
       if (!ext.equals("*")) exts[i++] = "." + ext;
     }
     if (i != exts.length) {
       String[] temp = new String[i];
       System.arraycopy(exts, 0, temp, 0, i);
       exts = temp;
     }
     return exts;
   } finally {
     pool.release();
   }
 }