--- ../../../../cvs/pear-core/PEAR/REST/10.php	2007-04-04 01:26:27.000000000 +0200
+++ REST/10.php	2007-04-12 14:19:04.000000000 +0200
@@ -538,9 +549,9 @@
         PEAR::popErrorHandling();
         return $ret;
     }
 
-    function listLatestUpgrades($base, $state, $installed, $channel, &$reg)
+    function listLatestUpgrades($base, $pref_state, $installed, $channel, &$reg)
     {
         $packagelist = $this->_rest->retrieveData($base . 'p/packages.xml');
         if (PEAR::isError($packagelist)) {
             return $packagelist;
@@ -551,16 +562,14 @@
         }
         if (!is_array($packagelist['p'])) {
             $packagelist['p'] = array($packagelist['p']);
         }
-        if ($state) {
-            $states = $this->betterStates($state, true);
-        }
         foreach ($packagelist['p'] as $package) {
             if (!isset($installed[strtolower($package)])) {
                 continue;
             }
             $inst_version = $reg->packageInfo($package, 'version', $channel);
+            $inst_state = $reg->packageInfo($package, 'release_state', $channel);
             PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
             $info = $this->_rest->retrieveData($base . 'r/' . strtolower($package) .
                 '/allreleases.xml');
             PEAR::popErrorHandling();
@@ -574,20 +583,34 @@
             $release = false;
             if (!is_array($info['r']) || !isset($info['r'][0])) {
                 $info['r'] = array($info['r']);
             }
+            // $info['r'] is sorted by version number
             foreach ($info['r'] as $release) {
                 if ($inst_version && version_compare($release['v'], $inst_version, '<=')) {
-                    continue;
+                    // not newer than the one installed
+                    break;
                 }
-                if ($state) {
-                    if (in_array($release['s'], $states)) {
+
+                // new version > installed version
+                if (!$pref_state) {
+                    // every state is a good state
+                    $found = true;
+                    break;
+                } else {
+                    $new_state = $release['s'];
+                    // if new state >= installed state: go
+                    if (in_array($new_state, $this->betterStates($inst_state, true))) {
                         $found = true;
                         break;
+                    } else {
+                        // only allow to lower the state of package,
+                        // if new state >= preferred state: go
+                        if (in_array($new_state, $this->betterStates($pref_state, true))) {
+                            $found = true;
+                            break;
+                        }
                     }
-                } else {
-                    $found = true;
-                    break;
                 }
             }
             if (!$found) {
                 continue;
