/// <summary>
        /// Trains a network.
        /// </summary>
        /// <param name="network">The network to train.</param>
        /// <param name="maxRunCount">The maximum number of runs.</param>
        /// <param name="maxIterationCout">The maximum number of iterations.</param>
        /// <param name="maxTolerableNetworkError">The maximum tolerable network error.</param>
        public TrainingLog Train(INetwork network, int maxRunCount, int maxIterationCout, double maxTolerableNetworkError)
        {
            // The backpropagation parameters.
            int  networkErrorUpdateInterval = 100;
            bool accumulatedLearning        = true;

            // Setup:
            // Decorate the network as backpropagation network.
            BackpropagationNetwork backpropagationNetwork = new BackpropagationNetwork(network);

            int    bestIterationCount = 0;
            double bestNetworkError   = backpropagationNetwork.CalculateError(trainingSet);

            double[] bestWeights = backpropagationNetwork.GetWeights();

            int runCount = 0;

            while ((runCount < maxRunCount) && (bestNetworkError > maxTolerableNetworkError))
            {
                int    iterationCount;
                double networkError;
                Train(backpropagationNetwork, maxIterationCout, out iterationCount, maxTolerableNetworkError, out networkError, networkErrorUpdateInterval, accumulatedLearning);

                if (networkError < bestNetworkError)
                {
                    bestIterationCount = iterationCount;
                    bestNetworkError   = networkError;
                    bestWeights        = backpropagationNetwork.GetWeights();
                }

                runCount++;

                // DEBUG
                Console.Write(".");
            }

            // DEBUG
            Console.WriteLine();

            backpropagationNetwork.SetWeights(bestWeights);

            // Teardown:
            // Undecorate the backpropagation network as network.
            network = backpropagationNetwork.GetDecoratedNetwork();

            // LOGGING
            // -------

            // Create the training log and log the training data.
            TrainingLog trainingLog = new TrainingLog(runCount, bestIterationCount, bestNetworkError);

            // Log the network statistics.
            LogNetworkStatistics(trainingLog, network);

            return(trainingLog);
        }