public static PluginState InstallFromZip(string type, string appPath)
 {
   //TODO: need to replace old version PluginState with new version
   PluginState ps = new PluginState(type);
   string pluginPath = Path.Combine(appPath, Settings.Default.PluginsDir);
   string zipPath = Directory.GetFiles(pluginPath, ps.Name + "*.zip").LastOrDefault();
   return InstallFromZip(zipPath, appPath, true);
 }
    public static PluginState InstallFromZip(string zipPath, string appPath, bool forceInstall)
    {
      string name = Path.GetFileNameWithoutExtension(zipPath);
      //string appPath = Path.GetDirectoryName(Path.GetDirectoryName(zipPath));
      PluginState ps = null;

      //read plugin entry and make sure compatible
      using (ZipInputStream s = new ZipInputStream(File.OpenRead(zipPath)))
      {
        ZipEntry e;
        while ((e = s.GetNextEntry()) != null)
        {
          if (e.Name.EndsWith(name + ".xml"))
          {
            Plugin p = new Plugin(XDocument.Load(new XmlTextReader(s)).Root);
            ps = new PluginState(p.Type);
            var compatible = p.CompatibleVersions.Select(cv => new Version(cv));
            if (!compatible.Contains(ServerApp.CurrentVersion))
              ps.Status = PluginStatus.Incompatible;
            else
              ps.Status = PluginStatus.NeedSetup;
            break;
          }
        }
      }
      if (ps == null) throw new PluginEntryNotFoundException(name); 

      if (ps.Status == PluginStatus.NeedSetup || forceInstall)
      {
        //exclude manifest when unzipping (it is embedded in dll anyway)
        string exclude = string.Format("-{0}$", name + ".xml");
        FastZip zip = new FastZip();
        zip.ExtractZip(zipPath, appPath, FastZip.Overwrite.Always, null, exclude, null, true);
      }
      return ps;
    }
 protected void RegisterPlugin(PluginState pluginEntry)
 {
   RegisterPlugin(pluginEntry.Type, pluginEntry);
 }
    protected void RegisterPlugin(string oldType, PluginState pluginEntry)
    {
      IList<PluginState> plugins = AtomPubService.GetService().Plugins.ToList();

      LogService.Info("Registering plugin {0}", pluginEntry.Type);
      var existing = plugins.Where(p => p.Type == oldType).SingleOrDefault();
      if (existing != null) plugins[plugins.IndexOf(existing)] = pluginEntry;
      else plugins.Add(pluginEntry);
      AppService svc = AtomPubService.GetService();
      svc.Plugins = plugins;
      AtomPubService.UpdateService(svc);
    }