'use strict'
var path = require('path')
var isDev = require('./is-dev.js').isDev
var npm = require('../npm.js')

module.exports = function (tree) {
  var pkg = tree.package
  var requiredBy = pkg._requiredBy.filter(function (req) { return req[0] !== '#' })
  var isTopLevel = tree.isTop
  var isChildOfTop = !isTopLevel && tree.parent.parent == null
  var isTopGlobal = isChildOfTop && tree.parent.path === path.resolve(npm.globalDir, '..')
  var topHasNoPackageJson = isChildOfTop && tree.parent.error
  return !isTopLevel && (!isChildOfTop || !topHasNoPackageJson) && !isTopGlobal && requiredBy.length === 0 && !isDev(tree)
}

@@ -10,174 +10,173 @@
 ct'%0A
-var path = require('path')%0Avar isDev = require('./is-dev.js').isDev%0Avar npm = require('../npm.js')%0A%0Amodule.exports = function (tree) %7B%0A  var pkg = tree.package%0A  var 
+module.exports = isExtraneous%0A%0Afunction isExtraneous (tree) %7B%0A  var result = !isNotExtraneous(tree)%0A  return result%0A%7D%0A%0Afunction isNotRequired (tree) %7B%0A  return tree.
 requ
@@ -186,15 +186,16 @@
 dBy 
-= pkg._
+&& tree.
 requ
@@ -205,39 +205,68 @@
 dBy.
-filter(function (req
+length === 0%0A%7D%0A%0Afunction parentHasNoPjson (tree
 ) %7B
+%0A 
  return 
 req%5B
@@ -265,393 +265,625 @@
 urn 
+t
 re
-q%5B0%5D !== '#' %7D)%0A  var isTopLevel = tree.isTop%0A  var isChildOfTop = !isTopLevel && tree.parent.parent == null%0A  var isTopGlobal = isChildOfTop && tree.parent.path === path.resolve(npm.globalDir, '..')%0A  var topHasNoPackageJson = isChildOf
+e.parent && tree.parent.isTop && tree.parent.error%0A%7D%0A%0Afunction topHasNoPjson (tree) %7B%0A  var top = tree%0A  while (!top.isTop) top = top.parent%0A  return top.error%0A%7D%0A%0Afunction isNotExtraneous (tree, isCycle) %7B%0A  if (!isCycle) isCycle = %7B%7D%0A  if (tree.is
 Top 
-&&
+%7C%7C
  tree.
-parent.error%0A
+userRequired) %7B%0A    return true%0A  %7D else if (isNotRequired(tree) && parentHasNoPjson(tree)) %7B%0A 
   
+ 
 return 
-!isTopLevel &&
+true%0A  %7D else if
  (
-!
 isC
-hildOfTop %7C%7C !topHasNoPackageJson) && !isTopGlobal && requiredBy.length === 0 && !isDev(tree)
+ycle%5Btree.path%5D) %7B%0A    return topHasNoPjson(tree)%0A  %7D else %7B%0A    isCycle%5Btree.path%5D = true%0A    return tree.requiredBy && tree.requiredBy.some(function (node) %7B%0A      return isNotExtraneous(node, Object.create(isCycle))%0A    %7D)%0A  %7D
 %0A%7D%0A

Rewrite to use the logical tree