private async Task<bool> Process(DataBatch batch, TcpResponse tcpResponse)
        {
            IRawClassifierTrainingContext<NetworkParameters> ctx = await GetOrCreateContext(batch);

            if (batch.Vectors.Any())
            {
                var iterations = batch.PropertyOrDefault("Iterations", 1);

                foreach (var i in Enumerable.Range(0, iterations))
                {
                    foreach (var inputOutputPair in batch
                        .Vectors
                        .Select(v => v.Split(ctx.Parameters.InputVectorSize))
                        .RandomOrder()
                        )
                    {
                        ctx.Train(inputOutputPair[1], inputOutputPair[0]);
                    }
                }
            }

            if (!batch.KeepAlive)
            {
                if (batch.PropertyOrDefault("SaveOutput", false))
                {
                    var network = (MultilayerNetwork)ctx.Output;

                    foreach (var prop in batch.Properties)
                    {
                        network.Properties[prop.Key] = prop.Value;
                    }

                    var name = batch.PropertyOrDefault("Name", batch.Id);

                    await _blobStore.StoreAsync(name, network);
                }

                ctx.Output.Save(tcpResponse.Content);

                _trainingContexts.Remove(batch.Id);
            }
            else
            {
                if (batch.SendResponse)
                {
                    WriteSummaryResponse(ctx, tcpResponse.Content);
                }
            }

            return true;
        }
        private async Task<IRawClassifierTrainingContext<NetworkParameters>> GetOrCreateContext(DataBatch batch)
        {
            IRawClassifierTrainingContext<NetworkParameters> ctx;

            //lock (_trainingContexts)
            {
                if (!_trainingContexts.TryGetValue(batch.Id, out ctx))
                {
                    var name = batch.PropertyOrDefault("Name", batch.Id);

                    var layerSizes = batch.Properties["LayerSizes"].Split(',').Select(s => int.Parse(s)).ToArray();
                    var networkParams = new NetworkParameters(layerSizes);

                    try
                    {
                        var network = new MultilayerNetwork(networkParams);

                        await _blobStore.RestoreAsync(name, network);

                        _trainingContexts[batch.Id] = ctx = _trainingContextFactory.Create(network);
                    }
                    catch
                    {
                        _trainingContexts[batch.Id] = ctx = _trainingContextFactory.Create(networkParams);
                    }
                }
            }

            return ctx;
        }