public IList<Gem> InstallGem(string gemname, Action<string> output)
        {
            IList<Gem> gems = new List<Gem>();

            // build list of gems and assemblies installed by nu in _root/lib
            output("> nu install " + gemname);
            foreach (var line in _runner.Run("cmd.exe", "/c nu install " + gemname, _rootPath))
            {
                output(line);
                if (line.StartsWith("Copy To:"))
                {
                    var installPath = line.Substring(9).Replace("/", "\\");
                    var name = Path.GetFileName(installPath);

                    var gem = new Gem { Name = name };
                    if (!gems.Contains(gem))
                    {
                        gems.Add(gem);
                        getAssemblies(gem, installPath);
                    }
                }
            }

            // for each gem, auto reference gems with 1 assembly (or configured auto-ref)
            // return rest to prompt user
            foreach (var gem in gems)
            {
                // if only 1 assembly in this gem, auto reference it
                if (gem.Assemblies.Count == 1 || gem.IsAutoReferenced)
                {
                    foreach (var assembly in gem.Assemblies)
                    {
                        output("Adding Reference: " + assembly);
                        _project.AddReference(assembly);
                        gem.IsReferenced = true;
                    }
                }
            }

            return gems;
        }
        public IEnumerable<Gem> SearchGems(string query, Action<string> output)
        {
            var gems = new List<Gem>();

            output("> " + _config.GemSearchCommand(query));
            var remoteGems = false;
            foreach (var line in _runner.Run("cmd.exe", "/c " + _config.GemSearchCommand(query)))
            {
                output(line);
                if (line == "*** REMOTE GEMS ***")
                {
                    remoteGems = true;
                    continue;
                }
                // parse line
                var m = Regex.Match(line, "(.+?)\\s\\((.+?)\\)");
                if (!m.Success) continue;
                var gem = new Gem
                              {
                                  Name = m.Groups[1].Value,
                                  Version = m.Groups[2].Value,
                                  IsRemote = remoteGems
                              };
                if (!gems.Contains(gem))
                {
                    gems.Add(gem);
                }
            }
            return gems;
        }
        private void getAssemblies(Gem gem, string installPath)
        {
            if (!_fs.FolderExists(installPath)) return;

            var currentFrameworkVersion = 0;

            // check for framework folders
            foreach (var folder in _fs.GetFolders(installPath))
            {
                var version = GetTargetFrameworkVersion(Path.GetFileName(folder));
                if (version != 0 && version > currentFrameworkVersion && version <= _targetFramework)
                {
                    currentFrameworkVersion = version;
                    installPath = folder;
                }
            }

            // look for auto-ref
            var autoref = _config.AutoReferences.FirstOrDefault(a => a.GemName == gem.Name);
            if (autoref != null)
            {
                gem.IsAutoReferenced = true;
                foreach (var path in autoref.Assemblies)
                {
                    var filePath = path.Replace("/", "\\");
                    // strip leading /
                    if (filePath.StartsWith("\\")) filePath = filePath.Substring(1);
                    // if ends with * then add all in path
                    if (filePath.EndsWith("*"))
                    {
                        foreach (var filename in _fs.GetFiles(Path.Combine(installPath, Path.GetDirectoryName(filePath))))
                        {
                            if (filename.EndsWith(".dll"))
                            {
                                gem.Assemblies.Add(filename);
                            }
                        }
                    }
                    else
                    {
                        gem.Assemblies.Add(Path.Combine(installPath, filePath));
                    }
                }
            }
            else
            {

                foreach (var filename in _fs.GetFiles(installPath))
                {
                    if (filename.EndsWith(".dll"))
                    {
                        gem.Assemblies.Add(filename);
                    }
                }
            }
        }
        public IEnumerable<Gem> ListGems()
        {
            var gems = new List<Gem>();

            foreach (var line in _runner.Run("cmd.exe", "/c " + _config.GemListCommand()))
            {
                // parse line
                var m = Regex.Match(line, "(.+?)\\s\\((.+?)\\)");
                if (!m.Success) continue;
                var gem = new Gem
                              {
                                  Name = m.Groups[1].Value,
                                  Version = m.Groups[2].Value
                              };
                getAssemblies(gem, Path.Combine(_libPath, gem.Name));
                gems.Add(gem);

                if (gem.Assemblies.Count == 0) continue;

                // count how many assemblies of this gem are currently referenced in project
                var refCount = gem.Assemblies.Count(filename => _project.HasReference(filename));

                // if assembly count equals ref count then gem is referenced
                if (gem.Assemblies.Count == refCount)
                {
                    gem.IsReferenced = true;
                }
            }
            return gems;
        }