diff --git a/data/src/main/java/core/DataProvider.java b/data/src/main/java/core/DataProvider.java
index 070b574d179d4cbca946eefd950ff69afce6ff3d..f714dadeacdc85800d7b4303380e932d2dea3bbe 100644
--- a/data/src/main/java/core/DataProvider.java
+++ b/data/src/main/java/core/DataProvider.java
@@ -11,19 +11,19 @@ import interfaces.Net;
 public class DataProvider {
   private static volatile Datacore dc;
 
-  void initData(Net net, Ihm ihm) throws DataException {
-    if (DataProvider.dc != null) {
+  public void initData(Net net, Ihm ihm) throws DataException {
+    if (DataProvider.dc == null) {
       DataProvider.dc = new Datacore(net, ihm);
     } else {
       throw new DataException("Datacore already initialized.");
     }
   }
 
-  DataForNet getDataForNet() {
+  public DataForNet getDataForNet() {
     return new DataForNetImpl();
   }
 
-  DataForIhm getDataForIhm() {
+  public DataForIhm getDataForIhm() {
     return new DataForIhmImpl();
   }
 }
diff --git a/data/src/main/java/core/Datacore.java b/data/src/main/java/core/Datacore.java
index 1874e95efab8c018244c59171b5a4bfae024e30c..98d81921e3a1c101296e06c27018b1fa5db41ac2 100644
--- a/data/src/main/java/core/Datacore.java
+++ b/data/src/main/java/core/Datacore.java
@@ -12,6 +12,7 @@ import java.util.UUID;
 import java.util.stream.Stream;
 
 public class Datacore {
+  public static final String LOCAL_USERS_FILENAME  = "lo23-users.ser";
   public Net net;
   public Ihm ihm;
   private volatile HashMap<UUID, User> users;
diff --git a/data/src/main/java/features/CreateUser.java b/data/src/main/java/features/CreateUser.java
new file mode 100644
index 0000000000000000000000000000000000000000..5080585d5615ea41f52b7c6e5fcf56d4f1f17303
--- /dev/null
+++ b/data/src/main/java/features/CreateUser.java
@@ -0,0 +1,67 @@
+package features;
+
+import core.Datacore;
+import datamodel.LocalUser;
+
+import java.io.EOFException;
+import java.io.File;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Properties;
+import javax.security.auth.login.LoginException;
+
+public abstract class CreateUser {
+  /**
+   * Check if there is a config.properties file in the user's save path.
+   * If there is no config file
+   * yet, create a config.properties file by copy of default-config.properties
+   * default-config.properties is located in resources/
+   * Then the function is calling Login.run function by giving
+   * the Datacore object and the LocalUser
+   *
+   * @param  user LocalUser given by IHM
+   */
+  public static void run(LocalUser user, Datacore dc, InputStream defaultPropInputStream)
+      throws IOException, LoginException {
+    //Create file config.properties
+    Properties defaultProp = new Properties();
+    Path userPropFilePath = user.getSavePath().resolve(user.getUsername() + "-config.properties");
+    File userConfigFile = new File(userPropFilePath.toString());
+
+    //If there is no config file for our user in the his path
+    if (!userConfigFile.exists()) {
+      if (defaultPropInputStream != null) {
+        defaultProp.load(defaultPropInputStream);
+      } else {
+        throw new FileNotFoundException(
+            "Warning: default property file not found in the resources path");
+      }
+      defaultProp.store(new FileOutputStream(userPropFilePath.toString()), null);
+    }
+
+    FileInputStream file = new FileInputStream(Paths.get(Datacore.LOCAL_USERS_FILENAME).toFile());
+    ObjectInputStream reader = new ObjectInputStream(file);
+    LocalUser otherUser;
+    try {
+      do {
+        otherUser = (LocalUser) reader.readObject();
+      } while (!(user.getUsername().equals(otherUser.getUsername())));
+    } catch (EOFException e) {
+      //Log user immediately after creation
+      Login.run(dc, user);
+      return;
+    } catch (ClassNotFoundException e) {
+      throw new LoginException("Local save may be corrupted or outdated");
+    }
+    throw new LoginException(("Username already exists"));
+  }
+}
+
+
diff --git a/data/src/main/java/features/Login.java b/data/src/main/java/features/Login.java
index 58cac192de318c126fdecab8b06ca37e0b46da38..86332597e13cbcc74a78328acf98c95ab818430a 100644
--- a/data/src/main/java/features/Login.java
+++ b/data/src/main/java/features/Login.java
@@ -73,7 +73,8 @@ public abstract class Login {
   public static void run(Datacore dc, String username, String password)
       throws IOException, LoginException {
     Path savePath = Paths.get("").toAbsolutePath();
-    LocalUser user = loadUserFromDisk(savePath.resolve("lo23-users.ser"), username, password);
+    LocalUser user = loadUserFromDisk(savePath.resolve(dc.LOCAL_USERS_FILENAME),
+        username, password);
     run(dc, user);
   }
 
diff --git a/data/src/main/java/interfaces/DataForIhmImpl.java b/data/src/main/java/interfaces/DataForIhmImpl.java
index 7f521e151502c122e3246997442b758dd3a4b7f1..e720a531d46132d472e7ad5a4960ba8eebf375a1 100644
--- a/data/src/main/java/interfaces/DataForIhmImpl.java
+++ b/data/src/main/java/interfaces/DataForIhmImpl.java
@@ -7,14 +7,17 @@ import datamodel.Music;
 import datamodel.MusicMetadata;
 import datamodel.SearchQuery;
 import datamodel.User;
+import features.CreateUser;
 import features.Login;
 import features.ShareMusicsPayload;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.io.InputStream;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
+
 import java.util.stream.Stream;
 import javax.security.auth.login.LoginException;
 
@@ -45,8 +48,10 @@ public class DataForIhmImpl implements DataForIhm {
   }
 
   @Override
-  public void createUser(LocalUser user) {
-    throw new UnsupportedOperationException("Not implemented yet");
+  public void createUser(LocalUser user) throws IOException, LoginException {
+    InputStream defaultPropInputStream = getClass().getClassLoader()
+        .getResourceAsStream("default-config.properties");
+    CreateUser.run(user, this.dc, defaultPropInputStream);
   }
 
   @Override
@@ -90,6 +95,12 @@ public class DataForIhmImpl implements DataForIhm {
     throw new UnsupportedOperationException("Not implemented yet");
   }
 
+  @Override
+  public MusicMetadata parseMusicMetadata(String path) {
+    throw new UnsupportedOperationException("Not implemented yet");
+  }
+
+
   @Override
   public void rateMusic(Music music, int rating) {
     throw new UnsupportedOperationException("Not implemented yet");
diff --git a/data/src/resources/default-config.properties b/data/src/resources/default-config.properties
new file mode 100644
index 0000000000000000000000000000000000000000..b8c3a66198733345afbabe24e202aed142a9f4a8
--- /dev/null
+++ b/data/src/resources/default-config.properties
@@ -0,0 +1 @@
+ips=""
\ No newline at end of file
diff --git a/ihm/src/main/java/core/IhmCore.java b/ihm/src/main/java/core/IhmCore.java
index e23f25b01eb8c0181e1b967bf9c932c67819400f..ed7a4c413c634fed30850c8e0c8fbea21004a9d3 100644
--- a/ihm/src/main/java/core/IhmCore.java
+++ b/ihm/src/main/java/core/IhmCore.java
@@ -5,6 +5,7 @@ import controllers.LoginController;
 import controllers.MainController;
 import controllers.SignUpController;
 
+import interfaces.DataForIhm;
 import java.awt.Toolkit;
 
 import javafx.application.Application;
@@ -16,74 +17,77 @@ import javafx.stage.Screen;
 import javafx.stage.Stage;
 
 /**
- *  the IhmCore will start the HCI of the Application, manages controllers and stage changes.
+ * the IhmCore will start the HCI of the Application, manages controllers and stage changes.
  */
 public class IhmCore extends Application {
 
   private Scene loginScene;
   private Scene signupScene;
   private Scene forgottenPasswordScene;
-  
+
   /**
    * the general scene.
    */
   private Stage primaryStage;
 
-  
+
   private MainController mainController;
   private LoginController loginController;
   private SignUpController signUpController;
   private ForgottenPasswordController forgottenPasswordController;
-  
+
   //private DataInterface dataInterface
-  
-  private IhmForData ihmForData;
-  
 
+  private IhmForData ihmForData;
+  private DataForIhm dataForIhm;
 
   private double width = Toolkit.getDefaultToolkit().getScreenSize().getWidth() / 2;
   private double height = Toolkit.getDefaultToolkit().getScreenSize().getHeight() / 2;
-  
+
   public IhmCore() {
     this.ihmForData = new IhmForData(this);
   }
 
-  
 
   /**
-   *  Setter for @see IhmForData.
-   *  @param ihmForData the integration of ihm interface
-  */
+   * Setter for @see IhmForData.
+   *
+   * @param ihmForData the integration of ihm interface
+   */
   public void setIhmForData(IhmForData ihmForData) {
     this.ihmForData = ihmForData;
   }
-  
+
   /**
-   *  Setter of @see MainController.
-   *  @param mainController the main Controller
-  */
+   * Setter of @see MainController.
+   *
+   * @param mainController the main Controller
+   */
   public void setMainController(MainController mainController) {
     this.mainController = mainController;
   }
 
   /**
    * Setter of @see LoginController.
+   *
    * @param loginController the login Controller
-  */
+   */
   public void setLoginController(LoginController loginController) {
     this.loginController = loginController;
   }
 
   /**
    * Setter of @see SignUpController.
+   *
    * @param signUpController the signup Controller
-  */
+   */
   public void setSignUpController(SignUpController signUpController) {
     this.signUpController = signUpController;
   }
 
   /**
    * Setter of @see ForgottenPasswordController.
+   *
    * @param forgottenPwdController the forgotten password Controller
    */
   public void setForgottenPasswordController(ForgottenPasswordController forgottenPwdController) {
@@ -92,38 +96,43 @@ public class IhmCore extends Application {
 
   /**
    * Getter of @see IhmForData.
+   *
    * @return @see IhmForData
    */
   public IhmForData getIhmForData() {
     return ihmForData;
   }
-  
+
   /**
    * Getter of @see MainController.
+   *
    * @return @see MainController
-  */
+   */
   public MainController getMainController() {
     return this.mainController;
   }
 
   /**
    * Getter of @see LoginController.
+   *
    * @return @see LoginController
-  */
+   */
   public LoginController getLoginController() {
     return this.loginController;
   }
 
   /**
    * Getter of @see SignUpController.
+   *
    * @return @see SignUpController
-  */
+   */
   public SignUpController getSignUpController() {
     return this.signUpController;
   }
 
   /**
    * Getter of @see ForgottenPasswordController.
+   *
    * @return @see ForgottenPasswordController
    */
   public ForgottenPasswordController getForgottenPasswordController() {
@@ -197,12 +206,12 @@ public class IhmCore extends Application {
     ForgottenPasswordController forgottenPasswordController =
         forgottenPasswordLoader.getController();
 
-    
+
     //set the Controllers link to acces from the controllers
     setLoginController(loginController);
     setSignUpController(signUpController);
     setForgottenPasswordController(forgottenPasswordController);
-    
+
     //set the IgmCore link into Controllers
     loginController.setIhmCore(this);
     signUpController.setIhmCore(this);
@@ -212,12 +221,12 @@ public class IhmCore extends Application {
     this.primaryStage = primaryStage;
 
     //primaryStage.initStyle(StageStyle.UNDECORATED);
-    
+
     //add the root scene (login)    
     primaryStage.setScene(loginScene);
     primaryStage.setResizable(false);
     primaryStage.show();
-    
+
     Rectangle2D primScreenBounds = Screen.getPrimary().getVisualBounds();
     primaryStage.setX((primScreenBounds.getWidth() - primaryStage.getWidth()) / 2);
     primaryStage.setY((primScreenBounds.getHeight() - primaryStage.getHeight()) / 2);
@@ -225,6 +234,7 @@ public class IhmCore extends Application {
 
   /**
    * function who is called from Main to start the HCI.
+   *
    * @param args the arguments of the Application from Main method
    */
   public void run(String[] args) {
@@ -235,4 +245,7 @@ public class IhmCore extends Application {
   }
 
 
+  public void setDataForIhm(DataForIhm dataForIhm) {
+    this.dataForIhm = dataForIhm;
+  }
 }
diff --git a/ihm/src/main/java/core/IhmForData.java b/ihm/src/main/java/core/IhmForData.java
index 613885ba9a0ec8576919e8f640d0090d765f2442..a0294515f5e3a70e19bdc9db621c22772399b8ba 100644
--- a/ihm/src/main/java/core/IhmForData.java
+++ b/ihm/src/main/java/core/IhmForData.java
@@ -1,8 +1,11 @@
 package core;
 
+import datamodel.Music;
+import datamodel.User;
+import interfaces.Ihm;
+
 /**
  * integration for Ihm interface.
- *
  */
 public class IhmForData implements Ihm {
 
@@ -11,7 +14,7 @@ public class IhmForData implements Ihm {
   public IhmForData(IhmCore ihmCore) {
     this.ihmCore = ihmCore;
   }
-    
+
   public IhmCore getIhmCore() {
     return this.ihmCore;
   }
@@ -19,66 +22,73 @@ public class IhmForData implements Ihm {
   /**
    * Notify IHM that a new User is connected. This is just a change update, there is no user list
    * exchange.
+   *
    * @param user User recently connected.
    */
   @Override
-  void notifyUserConnection(User user) {
-    throw new Exception("La fonction n'est pas encore implémentée");
+  public void notifyUserConnection(User user) {
+    throw new UnsupportedOperationException("La fonction n'est pas encore implémentée");
   }
 
   /**
    * Notify IHM that a User disconnected. This is just a change update, there is no user list
    * exchange.
+   *
    * @param user User recently disconnected.
    */
   @Override
-   void notifyUserDisconnection(User user) {
-    throw new Exception("La fonction n'est pas encore implémentée");
+  public void notifyUserDisconnection(User user) {
+    throw new UnsupportedOperationException("La fonction n'est pas encore implémentée");
   }
 
   /**
    * Update the IHM progress bar by giving the percentage of the download progression.
-   * @param music Music considered.
+   *
+   * @param music   Music considered.
    * @param integer Percentage progression, between 0 and 100.
    */
   @Override
-  void notifyDownloadProgress(Music music, int integer) {
-    throw new Exception("La fonction n'est pas encore implémentée");
+  public void notifyDownloadProgress(Music music, int integer) {
+    throw new UnsupportedOperationException("La fonction n'est pas encore implémentée");
   }
 
   /**
    * Trigger the update of all the occurrences of the modified music.
+   *
    * @param music Music to update.
    */
   @Override
-  void updateMusic(Music music) {
-    throw new Exception("La fonction n'est pas encore implémentée");
+  public void updateMusic(Music music) {
+    throw new UnsupportedOperationException("La fonction n'est pas encore implémentée");
   }
 
   /**
    * Notify that a music has been deleted.
+   *
    * @param music Deleted music.
    */
   @Override
-  void notifyMusicDeletion(Music music) {
-    throw new Exception("La fonction n'est pas encore implémentée");
+  public void notifyMusicDeletion(Music music) {
+    throw new UnsupportedOperationException("La fonction n'est pas encore implémentée");
   }
 
   /**
    * Trigger the update of all the occurrences of the modified user.
+   *
    * @param user User to update
    */
   @Override
-  void updateUser(User user) {
-    throw new Exception("La fonction n'est pas encore implémentée");
+  public void updateUser(User user) {
+    throw new UnsupportedOperationException("La fonction n'est pas encore implémentée");
   }
 
   /**
    * Notify that a User has been deleted.
+   *
    * @param user Deleted user.
    */
   @Override
-  void notifyUserDeletion(User user) {
-    throw new Exception("La fonction n'est pas encore implémentée");
+  public void notifyUserDeletion(User user) {
+    throw new UnsupportedOperationException("La fonction n'est pas encore implémentée");
   }
 }
\ No newline at end of file
diff --git a/interfaces/src/main/java/interfaces/DataForIhm.java b/interfaces/src/main/java/interfaces/DataForIhm.java
index b46663fcf33a9bf0671f659b13112e56414031c8..d177898aee3979058878fc1fa6f02e07906903a3 100644
--- a/interfaces/src/main/java/interfaces/DataForIhm.java
+++ b/interfaces/src/main/java/interfaces/DataForIhm.java
@@ -24,7 +24,15 @@ public interface DataForIhm {
 
   void addComment(Music music, String comment);
 
-  void createUser(LocalUser user);
+  /**
+   * Check if there is a config.properties file in the user's save path. If there is no config file
+   * yet, create a config.properties file by copy of default-config.properties
+   * default-config.properties is located in resources/
+   * Then the function is calling Login.run function by giving the Datacore object and the LocalUser
+   *
+   * @param  user LocalUser given by IHM
+   */
+  void createUser(LocalUser user) throws IOException, LoginException;
 
   void deleteAccount();
 
diff --git a/interfaces/src/main/java/interfaces/Ihm.java b/interfaces/src/main/java/interfaces/Ihm.java
index ae4f41c6cb61f005381d578edb640e09c1f0cf95..cc03db1cf320f3bd64300639ad67708f678253d2 100644
--- a/interfaces/src/main/java/interfaces/Ihm.java
+++ b/interfaces/src/main/java/interfaces/Ihm.java
@@ -14,7 +14,7 @@ public interface Ihm {
    *
    * @param user User recently connected.
    */
-  void notifyUserConnection(User user);
+  public void notifyUserConnection(User user);
 
   /**
    * Notify IHM that a User disconnected. This is just a change update, there is no user list
@@ -22,7 +22,7 @@ public interface Ihm {
    *
    * @param user User recently disconnected.
    */
-  void notifyUserDisconnection(User user);
+  public void notifyUserDisconnection(User user);
 
   /**
    * Update the IHM progress bar by giving the percentage of the download progression.
@@ -30,34 +30,34 @@ public interface Ihm {
    * @param music   Music considered.
    * @param integer Percentage progression, between 0 and 100.
    */
-  void notifyDownloadProgress(Music music, int integer);
+  public void notifyDownloadProgress(Music music, int integer);
 
   /**
    * Trigger the update of all the occurrences of the modified music.
    *
    * @param music Music to update.
    */
-  void updateMusic(Music music);
+  public void updateMusic(Music music);
 
   /**
    * Notify that a music has been deleted.
    *
    * @param music Deleted music.
    */
-  void notifyMusicDeletion(Music music);
+  public void notifyMusicDeletion(Music music);
 
   /**
    * Trigger the update of all the occurrences of the modified user.
    *
    * @param user User to update
    */
-  void updateUser(User user);
+  public void updateUser(User user);
 
   /**
    * Notify that a User has been deleted.
    *
    * @param user Deleted user.
    */
-  void notifyUserDeletion(User user);
+  public void notifyUserDeletion(User user);
 
 }
diff --git a/main/pom.xml b/main/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..53ca9aee3a37f1c9fae6061e9095b988ae70b7ed
--- /dev/null
+++ b/main/pom.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>lo23-root</artifactId>
+        <groupId>lo23</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>main</artifactId>
+    <dependencies>
+        <dependency>
+            <groupId>lo23</groupId>
+            <artifactId>data</artifactId>
+            <version>1.0-SNAPSHOT</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>lo23</groupId>
+            <artifactId>network</artifactId>
+            <version>1.0-SNAPSHOT</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>lo23</groupId>
+            <artifactId>interfaces</artifactId>
+            <version>1.0-SNAPSHOT</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>lo23</groupId>
+            <artifactId>ihm</artifactId>
+            <version>1.0-SNAPSHOT</version>
+            <scope>compile</scope>
+        </dependency>
+    </dependencies>
+
+
+</project>
\ No newline at end of file
diff --git a/main/src/main/java/Main.java b/main/src/main/java/Main.java
new file mode 100644
index 0000000000000000000000000000000000000000..e4599b17e6ee5312bf093fdbb30407d13c6dde81
--- /dev/null
+++ b/main/src/main/java/Main.java
@@ -0,0 +1,25 @@
+import core.DataProvider;
+import core.IhmCore;
+import exceptions.DataException;
+import provider.NetworkProvider;
+
+public class Main {
+  /**
+   * Initialize all the modules and starts the application.
+   */
+  public static void main(String[] args) {
+    IhmCore ihmCore = new IhmCore();
+    NetworkProvider networkProvider = new NetworkProvider();
+    DataProvider dataProvider = new DataProvider();
+
+    try {
+      dataProvider.initData(networkProvider.getNetwork(), ihmCore.getIhmForData());
+    } catch (DataException e) {
+      e.printStackTrace();
+    }
+    ihmCore.setDataForIhm(dataProvider.getDataForIhm());
+    networkProvider.setDataImpl(dataProvider.getDataForNet());
+
+    ihmCore.run(args);
+  }
+}
diff --git a/network/src/main/java/implementation/NetworkImpl.java b/network/src/main/java/implementation/NetworkImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..1658519398cd6e5e93cbb1e55ff2ef42813c2d2f
--- /dev/null
+++ b/network/src/main/java/implementation/NetworkImpl.java
@@ -0,0 +1,105 @@
+package implementation;
+
+import interfaces.Net;
+
+import java.io.Serializable;
+import java.net.InetAddress;
+import java.util.Collection;
+import java.util.stream.Stream;
+
+import provider.NetworkProvider;
+import threads.ThreadExtend;
+
+/**
+ * Implements the Net interface that provides useful methods to send messages through the
+ * network. Most of the times, simply redirect the request to the network provider because
+ * every thread-management is processed in provider.
+ * 
+ * @author Antoine
+ *
+ */
+public class NetworkImpl implements Net {
+
+  private NetworkProvider netProvider;
+  
+  /**
+   * Constructor that initializes the networkprovider, used to create the threads.
+   * 
+   * @param np current instance of the network provider
+   */
+  public NetworkImpl(NetworkProvider np) {
+    this.netProvider = np;
+  }
+  
+  /**
+   * Sends a message containing the string payload to the given ip.
+   * 
+   * @param payload content of the message
+   * @param ipDest ip address of the receiver
+   */
+  @Override
+  public void sendToUser(Serializable payload, InetAddress ipDest) {
+    this.netProvider.createSendToUserThread(payload, ipDest);
+  }
+  
+  /**
+   * Sends a message containing the string payload to the given ipS.
+   * 
+   * @param payload content of the message
+   * @param ipsDest ip addresses of the receivers
+   */
+  @Override
+  public void sendToUsers(Serializable payload, Stream<InetAddress> ipsDest) {
+    ipsDest.forEach((ip) -> netProvider.createSendToUserThread(payload, ip));
+  }
+  
+  /**
+   * TODO.
+   * 
+   * @param sourcesIPs ips where the music can be downloaded
+   * @param musicHash hash of the music to download
+   */
+  @Override
+  public void requestDownload(Stream<InetAddress> sourcesIPs, String musicHash) {
+    return;
+  }
+  
+  /**
+   * Connect the user to the network. Create a server thread to listen network and
+   * sends a payload to the known network.
+   * 
+   * @param payload data to transmit to the network
+   * @param knownIPs known nodes of the network
+   */
+  @Override
+  public void connect(Serializable payload, Collection<InetAddress> knownIPs) {
+    this.netProvider.createServer();
+    sendToUsers(payload, knownIPs.stream());
+  }
+  
+  /**
+   * Stop all interactions between user and network and notifies the network that
+   * the user has been disconnected.
+   * 
+   * @param payload data to inform the network we are disconnected
+   * @param knownIPs known ips in the network
+   */
+  @Override
+  public void disconnect(Serializable payload, Collection<InetAddress> knownIPs) {
+    //Kill server thread (we don't want to receive any messages)
+    this.netProvider.createServer().kill();
+    
+    //Wait for the network to be fully notified
+    this.netProvider.getNetwork().sendToUsers(payload, knownIPs.stream());
+    
+    //Then kill every running threads
+    for (ThreadExtend thread : this.netProvider.getThreads()) {
+      if (thread.isAlive()) {
+        thread.kill();
+      }
+    }
+    
+    //Clears the list of threads
+    this.netProvider.getThreads().clear();
+  }
+}
diff --git a/network/src/main/java/message/DownloadFile.java b/network/src/main/java/message/DownloadFile.java
new file mode 100644
index 0000000000000000000000000000000000000000..cbf14abd3650147b639ee0362201a2f210a96021
--- /dev/null
+++ b/network/src/main/java/message/DownloadFile.java
@@ -0,0 +1,39 @@
+package message;
+
+import interfaces.DataForNet;
+
+import java.io.Serializable;
+import java.net.InetAddress;
+import java.net.Socket;
+
+public class DownloadFile extends Message {
+
+  private String hashMusic;
+  private InetAddress ip;
+
+  public DownloadFile(Serializable p) {
+    super(p); //Call constructor for mother class
+    // To be define initialisation for hashMusic and ip
+  }
+
+  @Override
+  public void process(DataForNet data, Socket socket) {
+    //To be define
+  }
+
+  public String getHashMusic() {
+    return hashMusic;
+  }
+
+  public void setHashMusic(String hashMusic) {
+    this.hashMusic = hashMusic;
+  }
+
+  public InetAddress getIp() {
+    return ip;
+  }
+
+  public void setIp(InetAddress ip) {
+    this.ip = ip;
+  }
+}
diff --git a/network/src/main/java/message/Message.java b/network/src/main/java/message/Message.java
new file mode 100644
index 0000000000000000000000000000000000000000..1138e6f0f29ef43f6b590c37db60073ba2fe4a9f
--- /dev/null
+++ b/network/src/main/java/message/Message.java
@@ -0,0 +1,25 @@
+package message;
+
+import interfaces.DataForNet;
+
+import java.io.Serializable;
+import java.net.Socket;
+
+public class Message {
+
+  private Serializable payload;
+
+  public Message(Serializable p) {
+    this.payload = p;
+  }
+
+  public void process(DataForNet data, Socket socket){
+    //To be define
+  }
+
+  public Serializable getPayload() {
+    return payload;
+  }
+}
+
+
diff --git a/network/src/main/java/message/SendFile.java b/network/src/main/java/message/SendFile.java
new file mode 100644
index 0000000000000000000000000000000000000000..501d1198f62a8bf25791eb6c45c94038baff809d
--- /dev/null
+++ b/network/src/main/java/message/SendFile.java
@@ -0,0 +1,28 @@
+package message;
+
+import interfaces.DataForNet;
+
+import java.io.Serializable;
+import java.net.Socket;
+
+public class SendFile extends Message {
+  private String hashMusic;
+
+  public SendFile(Serializable p) {
+    super(p);
+    // To be define
+  }
+
+  @Override
+  public void process(DataForNet data, Socket socket) {
+    //To be define
+  }
+
+  public String getHashMusic() {
+    return hashMusic;
+  }
+
+  public void setHashMusic(String hashMusic) {
+    this.hashMusic = hashMusic;
+  }
+}
diff --git a/network/src/main/java/provider/NetworkProvider.java b/network/src/main/java/provider/NetworkProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..6b6645570138a47ed29704a7a4c333de0d8a9e2b
--- /dev/null
+++ b/network/src/main/java/provider/NetworkProvider.java
@@ -0,0 +1,135 @@
+package provider;
+
+import implementation.NetworkImpl;
+import interfaces.DataForNet;
+
+import java.io.Serializable;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.stream.Stream;
+
+import message.Message;
+
+import threads.MessageProcess;
+import threads.RequestDownloadThread;
+import threads.SendToUserThread;
+import threads.Server;
+import threads.ThreadExtend;
+
+/**
+ * Core class of network module. It stores references to every created threads
+ * and provide interface to interact with the module.
+ * 
+ * @author Antoine
+ *
+ */
+public class NetworkProvider {
+
+  public static final int N_PORT = 1026;
+  private DataForNet dataInterface;
+  private Server server;
+  private NetworkImpl netImpl;
+  private Collection<ThreadExtend> threads;
+
+  public NetworkProvider() {
+    this.netImpl = new NetworkImpl(this);
+    this.threads = new ArrayList<ThreadExtend>();
+  }
+
+  /**
+   * Simple getter for network implementation.
+   * 
+   * @return Current instance of the network implementation
+   */
+  public NetworkImpl getNetwork() {
+    return this.netImpl;
+  }
+
+  /**
+   * Create the server/listener thread and return the instance. If a server thread
+   * is already running, does not create a new instance but return the running one.
+   * 
+   * @return current instance of the server thread
+   */
+  public Server createServer() {
+    if (server == null || !server.isAlive()) {
+      this.server = new Server(this);
+      this.server.start();
+    }
+    //No need to recreate server
+    return this.server;
+  }
+
+  /**
+   * Simple getter for data interface implementation.
+   * 
+   * @return current instance of the implemetation of data interface
+   */
+  public DataForNet getDataImpl() {
+    return this.dataInterface;
+  }
+
+  /**
+   * Allows users to set the instance bind to the DataInterface interface.
+   * 
+   * @param dataInterface implementation of DataInterface
+   */
+  public void setDataImpl(DataForNet dataInterface) {
+    this.dataInterface = dataInterface;
+  }
+
+  
+  /**
+   * Create a new thread to process a given message. It adds the thread to the list of the
+   * running threads and return the instance.
+   * 
+   * @param m message to process
+   * @param s socket through which the message has been received
+   * @return created instance of the new thread
+   */
+  public MessageProcess createMessageProcess(Message m, Socket s) {
+    MessageProcess newThread = new MessageProcess(m, s, this);
+    threads.add(newThread);
+    newThread.start();
+    return newThread;
+  }
+
+  /**
+   * Create a new dedicated thread to send a message to a given user, and returns the
+   * instance of the newly created thread.
+   * 
+   * @param p payload to be sent in the message
+   * @param ip ip address of the receiver
+   * @return instance of the newly created thread
+   */
+  public SendToUserThread createSendToUserThread(Serializable p, InetAddress ip) {
+    SendToUserThread newThread = new SendToUserThread(p, ip);
+    threads.add(newThread);
+    newThread.start();
+    return newThread;
+  }
+
+  /**
+   * Create a new dedicated thread to send a download request to a given set of users,
+   * and returns the instance of the newly created thread.
+   * 
+   * @param ownersIps ips where the music can be downloaded
+   * @param musicHash hash of the desired music
+   * @return instance of the newly created thread
+   */
+  public RequestDownloadThread createRequestDownloadThread(Stream<InetAddress> ownersIps,
+      String musicHash) {
+    return null;
+  }
+  
+  /**
+   * Simple getter for threads.
+   * 
+   * @return collection of the current running threads
+   */
+  public Collection<ThreadExtend> getThreads() {
+    return this.threads;
+  }
+}
diff --git a/network/src/main/java/threads/MessageProcess.java b/network/src/main/java/threads/MessageProcess.java
new file mode 100644
index 0000000000000000000000000000000000000000..fbc721549433a590bd468ebf6a69f62481108067
--- /dev/null
+++ b/network/src/main/java/threads/MessageProcess.java
@@ -0,0 +1,46 @@
+package threads;
+
+import java.net.Socket;
+
+import message.Message;
+import provider.NetworkProvider;
+
+/**
+ * Class that will execute the appropriate behaviour depending on the given message
+ * given in constructor. It is just supposed to execute message.process(...) in a 
+ * separate thread in order not to block the application.
+ * 
+ * @author Antoine
+ *
+ */
+public class MessageProcess extends ThreadExtend {
+
+  private Message message;
+  private Socket socket;
+  private NetworkProvider netProvider;
+  
+
+  /**
+   * Simple constructor.
+   * 
+   * @param m : message received, will call m.process
+   * @param s : socket through which the message has been received
+   * @param np : current instance of the networkProvider
+   */
+  public MessageProcess(Message m, Socket s, NetworkProvider np) {
+    this.message = m;
+    this.socket = s;
+    this.netProvider = np;
+  }
+  
+  @Override
+  public void run() {
+    // TODO Auto-generated method stub
+  }
+
+  @Override
+  public void kill() {
+    // TODO Auto-generated method stub
+  }
+
+}
diff --git a/network/src/main/java/threads/RequestDownloadThread.java b/network/src/main/java/threads/RequestDownloadThread.java
new file mode 100644
index 0000000000000000000000000000000000000000..75db1b29ce733f5c6284f00d17bbfe72f0df2fc9
--- /dev/null
+++ b/network/src/main/java/threads/RequestDownloadThread.java
@@ -0,0 +1,25 @@
+package threads;
+
+import java.net.InetAddress;
+import java.util.stream.Stream;
+
+public class RequestDownloadThread extends ThreadExtend {
+
+  private Stream<InetAddress> ownersIps;
+  private String musicHash;
+
+  public RequestDownloadThread(Stream<InetAddress> ownersIps, String musicHash) {
+    this.ownersIps = ownersIps;
+    this.musicHash = musicHash;
+  }
+
+  @Override
+  public void run() {
+    
+  }
+
+  @Override
+  public void kill() {
+
+  }
+}
diff --git a/network/src/main/java/threads/SendToUserThread.java b/network/src/main/java/threads/SendToUserThread.java
new file mode 100644
index 0000000000000000000000000000000000000000..6d40668b89f92250ce6afdb21ca97152f3bc39c9
--- /dev/null
+++ b/network/src/main/java/threads/SendToUserThread.java
@@ -0,0 +1,43 @@
+package threads;
+
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.net.InetAddress;
+import java.net.Socket;
+import message.Message;
+import provider.NetworkProvider;
+
+public class SendToUserThread extends ThreadExtend {
+  private Serializable payload;
+  private InetAddress ipDest;
+
+  /**
+   * create a socket to send a payload to a user.
+   * @param p payload of message to send
+   * @param ip ip address of the destination
+   */
+  public SendToUserThread(Serializable p, InetAddress ip) {
+    this.payload = p;
+    this.ipDest = ip;
+  }
+
+  @Override
+  public void run() {
+    System.out.println("Send message to a user");
+    try {
+      Socket socket = new Socket(this.ipDest, NetworkProvider.N_PORT);
+      OutputStream outputStream = socket.getOutputStream();
+      ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
+      objectOutputStream.writeObject(new Message(this.payload));
+      socket.close();
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+  }
+
+  @Override
+  public void kill() {
+    System.out.println("Stop Sending payload to a user");
+  }
+}
diff --git a/network/src/main/java/threads/Server.java b/network/src/main/java/threads/Server.java
new file mode 100644
index 0000000000000000000000000000000000000000..2f30b23442ab136dd98bc39b1d7268ca0a6a62c2
--- /dev/null
+++ b/network/src/main/java/threads/Server.java
@@ -0,0 +1,68 @@
+package threads;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+import message.Message;
+import provider.NetworkProvider;
+
+/**
+ * Server class running in a different thread. It listens to the default
+ * port and will ask network provider to process messages in another thread when
+ * a message is received.
+ * 
+ * @author Antoine
+ */
+public class Server extends Thread {
+
+  private ServerSocket listeningSocket;
+  private NetworkProvider netProvider;
+  private boolean serverRunning = true;
+  
+  /**
+   * Constructor that initiates the network provider with the current instance.
+   * 
+   * @param n current instance of the NetworkProvider
+   */
+  public Server(NetworkProvider n) {
+    this.netProvider = n;
+  }
+  
+  /**
+   * Should end 'properly' the thread execution.
+   */
+  public void kill() {
+    this.serverRunning = false;
+    try {
+      this.listeningSocket.close();
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
+  }
+  
+  /**
+   * Infinite loop that wait for messages to be received and request the network
+   * provider to process the message in another thread.
+   */
+  @Override
+  public void run() {
+    try {
+      this.listeningSocket = new ServerSocket(NetworkProvider.N_PORT);
+      while (this.serverRunning) {
+        System.out.println("Waiting for connection...");
+        
+        Socket socket = this.listeningSocket.accept();
+        
+        ObjectInputStream receivedObject = new ObjectInputStream(socket.getInputStream());
+        
+        Message receivedMessage = (Message) receivedObject.readObject();
+        this.netProvider.createMessageProcess(receivedMessage, socket);
+      }
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+  }
+
+}
diff --git a/network/src/main/java/threads/ThreadExtend.java b/network/src/main/java/threads/ThreadExtend.java
new file mode 100644
index 0000000000000000000000000000000000000000..47001202479629df020287081c30f0a3a7cf609b
--- /dev/null
+++ b/network/src/main/java/threads/ThreadExtend.java
@@ -0,0 +1,9 @@
+package threads;
+
+/**
+ * Abstract class that only adds a method 'kill' to the Thread class. The method 'kill'
+ * should be used to stop properly a thread.
+ */
+public abstract class ThreadExtend extends Thread {
+  public abstract void kill();
+}
diff --git a/pom.xml b/pom.xml
index 027032846fd9266acedfda462fb75e6ee0710238..57461598bdb32f8e2ad5725fe8d3bd8eda53e597 100644
--- a/pom.xml
+++ b/pom.xml
@@ -19,6 +19,7 @@
         <module>ihm</module>
         <module>interfaces</module>
         <module>data-model</module>
+        <module>main</module>
     </modules>
 
     <build>