diff --git a/src/Network/NeuralNetwork.cpp b/src/Network/NeuralNetwork.cpp
index ee9fb4739242b171b09f4b1edc826d3c56eae023..445c736ac54db4a99f772b0c04e878bcd370cbf6 100644
--- a/src/Network/NeuralNetwork.cpp
+++ b/src/Network/NeuralNetwork.cpp
@@ -8,10 +8,10 @@
 #include <iostream>
 #include <4neuro.h>
 
-#include "../message.h"
+#include "message.h"
 #include "NeuralNetwork.h"
 #include "NeuralNetworkSerialization.h"
-#include "../exceptions.h"
+#include "exceptions.h"
 
 
 namespace lib4neuro {
@@ -144,8 +144,11 @@ namespace lib4neuro {
 
     }
 
-    NeuralNetwork *NeuralNetwork::get_subnet(std::vector<size_t> &input_neuron_indices,
+    NeuralNetwork *NeuralNetwork::get_subnet(::std::vector<size_t> &input_neuron_indices,
                                              ::std::vector<size_t> &output_neuron_indices) {
+
+        THROW_NOT_IMPLEMENTED_ERROR();
+
         NeuralNetwork *output_net = nullptr;
 // TODO rework due to the changed structure of the class
 //    Neuron * active_neuron, * target_neuron;
@@ -433,11 +436,11 @@ namespace lib4neuro {
     void NeuralNetwork::copy_parameter_space(std::vector<double> *parameters) {
         if (parameters != nullptr) {
             for (unsigned int i = 0; i < this->connection_weights->size(); ++i) {
-                (*this->connection_weights)[i] = (*parameters)[i];
+                (*this->connection_weights).at(i) = (*parameters).at(i);
             }
 
             for (unsigned int i = 0; i < this->neuron_biases->size(); ++i) {
-                (*this->neuron_biases)[i] = (*parameters)[i + this->connection_weights->size()];
+                (*this->neuron_biases).at(i) = (*parameters).at(i + this->connection_weights->size());
             }
         }
     }
@@ -459,7 +462,7 @@ namespace lib4neuro {
         this->delete_weights = false;
     }
 
-    void NeuralNetwork::eval_single(std::vector<double> &input, ::std::vector<double> &output,
+    void NeuralNetwork::eval_single(::std::vector<double> &input, ::std::vector<double> &output,
                                     ::std::vector<double> *custom_weights_and_biases) {
         if ((this->input_neuron_indices->size() * this->output_neuron_indices->size()) <= 0) {
             THROW_INVALID_ARGUMENT_ERROR("Input and output neurons have not been specified!");
@@ -681,26 +684,91 @@ namespace lib4neuro {
         }
     }
 
-    void NeuralNetwork::print_weights() {
-        printf("Connection weights: ");
+    void NeuralNetwork::write_weights() {
+        std::cout << "Connection weights: ";
+        if (this->connection_weights) {
+            for (size_t i = 0; i < this->connection_weights->size() - 1; ++i) {
+                std::cout << this->connection_weights->at(i) << ", ";
+            }
+            std::cout << this->connection_weights->at(this->connection_weights->size() - 1) << std::endl;
+        }
+    }
+
+    void NeuralNetwork::write_weights(std::string file_path) {
+        std::ofstream ofs(file_path);
+
+        if(!ofs.is_open()) {
+            THROW_RUNTIME_ERROR("File " + file_path + " can not be opened!");
+        }
+
+        ofs << "Connection weights: ";
+
+        if (this->connection_weights) {
+            for (size_t i = 0; i < this->connection_weights->size() - 1; ++i) {
+                ofs << this->connection_weights->at(i) << ", ";
+            }
+            ofs << this->connection_weights->at(this->connection_weights->size() - 1) << std::endl;
+        }
+    }
+
+    void NeuralNetwork::write_weights(std::ofstream* file_path) {
+        *file_path << "Connection weights: ";
+
         if (this->connection_weights) {
             for (size_t i = 0; i < this->connection_weights->size() - 1; ++i) {
-                printf("%f, ", this->connection_weights->at(i));
+                *file_path << this->connection_weights->at(i) << ", ";
             }
-            printf("%f", this->connection_weights->at(this->connection_weights->size() - 1));
+            *file_path << this->connection_weights->at(this->connection_weights->size() - 1) << std::endl;
         }
+    }
 
-        printf("\n");
+    void NeuralNetwork::write_biases() {
+        std::cout << "Network biases: ";
+
+        if(this->neuron_biases) {
+            for(unsigned int i = 0; i < this->neuron_biases->size() - 1; i++) {
+                std::cout << this->neuron_biases->at(i) << ", ";
+            }
+            std::cout << this->neuron_biases->at(this->neuron_biases->size() - 1) << std::endl;
+        }
     }
 
-    void NeuralNetwork::print_stats() {
+    void NeuralNetwork::write_biases(std::string file_path) {
+        std::ofstream ofs(file_path);
+
+        if(!ofs.is_open()) {
+            THROW_RUNTIME_ERROR("File " + file_path + " can not be opened!");
+        }
+
+        ofs << "Network biases: ";
+
+        if(this->neuron_biases) {
+            for(unsigned int i = 0; i < this->neuron_biases->size() - 1; i++) {
+                ofs << this->neuron_biases->at(i) << ", ";
+            }
+            ofs << this->neuron_biases->at(this->neuron_biases->size() - 1) << std::endl;
+        }
+    }
+
+    void NeuralNetwork::write_biases(std::ofstream* file_path) {
+        *file_path << "Network biases: ";
+
+        if(this->neuron_biases) {
+            for(unsigned int i = 0; i < this->neuron_biases->size() - 1; i++) {
+                *file_path << this->neuron_biases->at(i) << ", ";
+            }
+            *file_path << this->neuron_biases->at(this->neuron_biases->size() - 1) << std::endl;
+        }
+    }
+
+    void NeuralNetwork::write_stats() {
         ::std::cout << "Number of neurons: " << this->neurons->size() << ::std::endl
                     << "Number of connections: " << this->connection_list->size() << ::std::endl
                     << "Number of active weights: " << this->connection_weights->size() << ::std::endl
                     << "Number of active biases: " << this->neuron_biases->size() << ::std::endl;
 
         if(this->normalization_strategy) {
-            ::std::cout << "Normalization stratey maximum value: "
+            ::std::cout << "Normalization strategy maximum value: "
                         << this->normalization_strategy->get_max_value() << std::endl
                         << "Normalization strategy minimum value: "
                         << this->normalization_strategy->get_min_value()
@@ -708,6 +776,44 @@ namespace lib4neuro {
         }
     }
 
+    void NeuralNetwork::write_stats(std::string file_path) {
+        std::ofstream ofs(file_path);
+
+        if(!ofs.is_open()) {
+            THROW_RUNTIME_ERROR("File " + file_path + " can not be opened!");
+        }
+
+        ofs << "Number of neurons: " << this->neurons->size() << ::std::endl
+            << "Number of connections: " << this->connection_list->size() << ::std::endl
+            << "Number of active weights: " << this->connection_weights->size() << ::std::endl
+            << "Number of active biases: " << this->neuron_biases->size() << ::std::endl;
+
+        if(this->normalization_strategy) {
+            ofs << "Normalization strategy maximum value: "
+                << this->normalization_strategy->get_max_value() << std::endl
+                << "Normalization strategy minimum value: "
+                << this->normalization_strategy->get_min_value()
+                << std::endl;
+        }
+
+        ofs.close();
+    }
+
+    void NeuralNetwork::write_stats(std::ofstream* file_path) {
+        *file_path << "Number of neurons: " << this->neurons->size() << ::std::endl
+                   << "Number of connections: " << this->connection_list->size() << ::std::endl
+                   << "Number of active weights: " << this->connection_weights->size() << ::std::endl
+                   << "Number of active biases: " << this->neuron_biases->size() << ::std::endl;
+
+        if(this->normalization_strategy) {
+            *file_path << "Normalization strategy maximum value: "
+                       << this->normalization_strategy->get_max_value() << std::endl
+                       << "Normalization strategy minimum value: "
+                       << this->normalization_strategy->get_min_value()
+                       << std::endl;
+        }
+    }
+
     std::vector<double> *NeuralNetwork::get_parameter_ptr_biases() {
         return this->neuron_biases;
     }
@@ -929,9 +1035,9 @@ namespace lib4neuro {
         unsigned int inp_dim = neuron_numbers->at(0);  //!< Network input dimension
         unsigned int out_dim = neuron_numbers->back(); //!< Network output dimension
 
-        COUT_DEBUG(<< "Fully connected feed-forward network:" << std::endl)
-        COUT_DEBUG(<< "# of inputs: " << inp_dim << std::endl);
-        COUT_DEBUG(<< "# of outputs: " << out_dim << std::endl);
+        COUT_DEBUG("Fully connected feed-forward network being constructed:" << std::endl);
+        COUT_DEBUG("# of inputs: " << inp_dim << std::endl);
+        COUT_DEBUG("# of outputs: " << out_dim << std::endl);
 
         std::vector<size_t> input_layer_neuron_indices;
         std::vector<size_t> previous_layer_neuron_indices;
@@ -947,9 +1053,8 @@ namespace lib4neuro {
         input_layer_neuron_indices = current_layer_neuron_indices;
 
         /* Creation of HIDDEN layers */
-
         for(unsigned int i = 1; i <= neuron_numbers->size()-2; i++) {
-            COUT_DEBUG(<< "Hidden layer #d: " << neuron_numbers->at(i) << " neurons" << std::endl);
+            COUT_DEBUG("Hidden layer #" << i << ": " << neuron_numbers->at(i) << " neurons" << std::endl);
             previous_layer_neuron_indices.reserve(neuron_numbers->at(i-1));
             previous_layer_neuron_indices = current_layer_neuron_indices;
             current_layer_neuron_indices.clear();
@@ -967,7 +1072,7 @@ namespace lib4neuro {
                     }
 
                     case NEURON_TYPE::CONSTANT: {
-                        neuron_id = this->add_neuron(new NeuronConstant, BIAS_TYPE::NEXT_BIAS);
+                        THROW_INVALID_ARGUMENT_ERROR("Constant neurons can't be used in fully connected feed-forward networks!");
                         break;
                     }
 
diff --git a/src/Network/NeuralNetwork.h b/src/Network/NeuralNetwork.h
index 598833aa1c890d934d20cb27701d3cc34483f1aa..ba0e7aea6559861171827b54dd21c2813b9afe4d 100644
--- a/src/Network/NeuralNetwork.h
+++ b/src/Network/NeuralNetwork.h
@@ -332,12 +332,52 @@ namespace lib4neuro {
         /**
          *
          */
-        LIB4NEURO_API void print_weights();
+        LIB4NEURO_API void write_weights();
 
         /**
          *
          */
-        LIB4NEURO_API void print_stats();
+        LIB4NEURO_API void write_weights(std::string file_path);
+
+        /**
+         *
+         * @param file_path
+         */
+        LIB4NEURO_API void write_weights(std::ofstream* file_path);
+
+        /**
+         *
+         */
+        LIB4NEURO_API void write_biases();
+
+        /**
+         *
+         * @param file_name
+         */
+        LIB4NEURO_API void write_biases(std::string file_path);
+
+        /**
+         *
+         * @param file_path
+         */
+        LIB4NEURO_API void write_biases(std::ofstream* file_path);
+
+        /**
+         *
+         */
+        LIB4NEURO_API void write_stats();
+
+        /**
+         *
+         * @param file_path
+         */
+        LIB4NEURO_API void write_stats(std::string file_path);
+
+        /**
+         *
+         * @param file_path
+         */
+        LIB4NEURO_API void write_stats(std::ofstream* file_path);
 
         /**
          *