public void Can_install_plugin()
        {
            string pluginName = "mobz/elasticsearch-head";
            using (var elasticsearch = new Elasticsearch(c => c.AddPlugin(new Configuration.Plugin(pluginName))))
            {
                ////Arrange
                var client = new ElasticClient(new ConnectionSettings(elasticsearch.Url));

                ////Act
                var result = client.CatPlugins();

                int pluginCount = 0;
                foreach (CatPluginsRecord plugin in result.Records)
                {
                    pluginCount++;
                }

                ////Assert
                Assert.That(result.IsValid);
                Assert.AreEqual(1, pluginCount);
            }
        }
        public void Can_install_plugin_url()
        {
            string pluginName = "test_plugin_135076"; // random numbers to make sure the name doesn't conflict with publicly available plugins
            string pluginUrl = "file:///" + Directory.GetCurrentDirectory() + "/TestFiles/test_plugin_135076.zip";
            using (var elasticsearch = new Elasticsearch(c => c.AddPlugin(new Configuration.Plugin(pluginName, pluginUrl))))
            {
                ////Arrange
                var client = new ElasticClient(new ConnectionSettings(elasticsearch.Url));

                ////Act
                var result = client.CatPlugins();

                int pluginCount = 0;
                foreach (CatPluginsRecord plugin in result.Records)
                {
                    pluginCount++;
                }

                ////Assert
                Assert.That(result.IsValid);
                Assert.AreEqual(1, pluginCount);
            }
        }
		public IObservable<ElasticsearchMessage> Start()
		{

			if (!this.RunningIntegrations) return Observable.Empty<ElasticsearchMessage>();

			this.Stop();
			var timeout = TimeSpan.FromSeconds(60);
			var handle = new ManualResetEvent(false);

			if (_doNotSpawnIfAlreadyRunning)
			{
			    var client = new ElasticClient();
			    var alreadyUp = client.RootNodeInfo();
				if (alreadyUp.IsValid)
				{
				    var checkPlugins = client.CatPlugins();

				    if (checkPlugins.IsValid)
				    {
				        foreach (var supportedPlugin in  SupportedPlugins)
				        {
				            if (!checkPlugins.Records.Any(r => r.Component.Equals(supportedPlugin.Key)))
				                throw new ApplicationException($"Already running elasticsearch does not have supported plugin {supportedPlugin.Key} installed.");
				        }

				        this.Started = true;
				        this.Port = 9200;
				        this.Info = new ElasticsearchNodeInfo(alreadyUp.Version.Number, null, alreadyUp.Version.LuceneVersion);
				        this._blockingSubject.OnNext(handle);
				        if (!handle.WaitOne(timeout, true))
				            throw new ApplicationException($"Could not launch tests on already running elasticsearch within {timeout}");

				        return Observable.Empty<ElasticsearchMessage>();
				    }
				}
			}

		    lock (_lock)
		    {
		        InstallPlugins();
		    }

			this._process = new ObservableProcess(this.Binary,
				$"-Des.cluster.name={this.ClusterName}",
				$"-Des.node.name={this.NodeName}",
				$"-Des.path.repo={this.RepositoryPath}",
				$"-Des.script.inline=on",
				$"-Des.script.indexed=on"
			);
			var observable = Observable.Using(() => this._process, process => process.Start())
				.Select(consoleLine => new ElasticsearchMessage(consoleLine));
			this._processListener = observable.Subscribe(onNext: s => HandleConsoleMessage(s, handle));

			if (!handle.WaitOne(timeout, true))
			{
				this.Stop();
				throw new ApplicationException($"Could not start elasticsearch within {timeout}");
			}

			return observable;
		}