diff --git a/essential_rust.tex b/essential_rust.tex
index 7fa5c5e7721475ce96d2c715af3b7c5e8149d6fc..c3c4be0156451a1c93a41e64fca4b21bda75130d 100644
--- a/essential_rust.tex
+++ b/essential_rust.tex
@@ -244,18 +244,17 @@ fn add(x: i32, y: i32) -> i32 {
 \newpage
 
 
-\subsection{Chaînes de caractères (introduction)}
-
-Pour une explication plus poussée des différents types de chaînes de caractères,
-voir \Cref{advancedStrings}.
+\subsection{Chaînes de caractères}
 
-Les chaînes de caractères en Rust sont toutes encodés en \texttt{UTF-8}, et
-prennent principalement l'un des deux formats suivants :
+Les chaînes de caractères en Rust supportent \texttt{UTF-8}, et
+prennent principalement un format parmi :
 \begin{itemize}
-  \item chaîne de caractères allouée dynamiquement (type \texttt{String}).
-  \item référence non modifiable, nommée slice (type \texttt{\&str}).
+    \item chaîne de caractères allouée dynamiquement (type \texttt{String})
+    \item référence non modifiable, nommée slice (type \texttt{\&str})
+    \item tableau d'octets, surtout utilisé pour la compatibilité avec C (type \texttt{\&[u8]})
 \end{itemize}
 
+On peut facilement convertir d'un type à un autre.
 \begin{lstlisting}[style=Rust, language=Rust]
 fn main() {
     // Une chaîne entre "" est une \&str
@@ -276,15 +275,17 @@ fn main() {
 }
 \end{lstlisting}
 
-Il y a des choses qu'on peut ou ne peut pas faire avec ces deux formats :
+Il y a des choses qu'on peut ou ne peut pas faire avec ces formats :
 \begin{itemize}
     \item on ne peut pas modifier une \texttt{\&str}, alors que \texttt{String}
         a des méthodes pour être modifiée
+    \item on peut lire et modifier des octets individuels de \texttt{\&[u8]}
+        mais ce type ne gère pas l'UTF-8 et n'est pas affichable tel quel
     \item on ne peut pas additionner (concaténer) deux \texttt{String} alors qu'on peut
         additionner \texttt{\&str + \&str} ou encore \texttt{String + \&str}
 \end{itemize}
 Pour beaucoup de raisons il y a dans la librairie standard des fonctions qui demandent
-l'un ou l'autre type. Heureusement la conversion est facile.
+un type ou un autre, donc les conversions sont fréquentes.
 
 
 On verra souvent des erreurs de compilation comme celle-ci :
@@ -662,13 +663,13 @@ fn main() {
         name: "Anthony".to_string(),
         nickname: Nickname::Some("Antho".to_string()),
     };
-    
+
     let user_two: User = User {
         id: 2,
         name: "Luc".to_string(),
         nickname: Nickname::None,
     };
-   
+
     print_user(user_one);   // "1: Anthony aka Antho"
     print_user(user_two);   // "2: Luc"
 }
@@ -996,18 +997,18 @@ fn read_file() -> Result<String, io::Error> {
 
 Tous les programmes doivent gérer la façon dont ils utilisent la mémoire.
 \begin{itemize}
-  \item Certains langages comme Java ou Go ou OCaml, utilisent un ramasse-miette
-      détectant la mémoire qui n'est plus utilisée.
-  \item D'autres comme le C ou l'assembleur, requierent que le développeur
-      gère explicitement l'allocation et la désallocation de la mémoire.
+    \item Certains langages (comme Java ou Go ou OCaml) utilisent un ramasse-miette
+        détectant la mémoire qui n'est plus utilisée.
+    \item D'autres comme le C ou l'assembleur, requièrent que le développeur
+        gère explicitement l'allocation et la désallocation de la mémoire.
 \end{itemize}
 La première approche a l'inconvénient de causer des chutes de performance quand le
 ramasse-miettes s'exécute, et nécessite souvent que tous les objets se trouvent
 derrière une couche supplémentaire de pointeurs.
-
 La seconde est source de bugs.\\
 
 Rust utilise une autre approche : la mémoire est gérée par un système d'appartenance
+(parfois appelé possession ou ownership)
 qui est vérifié à la compilation et qui permet de décider déterministiquement
 à quel moment chaque valeur est libérée.\\
 
@@ -1071,7 +1072,9 @@ fn main() {
 }
 \end{lstlisting}
 
-La libération se fait grâce à l'appel de \texttt{drop} dans le trait \texttt{std::ops::Drop}.\\
+La libération se fait grâce à l'appel de \texttt{drop} dans le trait \texttt{std::ops::Drop}.
+Cette fonction est appelée automatiquement par le compilateur si elle n'est pas déjà
+invoquée explicitement.\\
 
 Grâce aux règles de possession, cette fonction est souvent très facile à implémenter :
 
@@ -1084,39 +1087,74 @@ La méthode \texttt{drop} prend possession de \texttt{self}... et ne fait rien d
 \texttt{self} sera libéré, puisque son nouveau possesseur cessera d'exister à la
 fin du corps de la fonction.
 
-
-
 \newpage
 
-Concernant l'appartenance, le déplacement se comporte de deux façons :
-\begin{itemize}
-  \item Si la valeur est uniquement dans la \texttt{pile} : un \textit{deep copy} sera effectué, cela permet de copier l'ensemble de la structure dans la nouvelle variable.
-  \item Si la valeur utilise le \texttt{tas} : un \textit{shallow copy} sera effectué, la variable déplacée devient invalide.
-\end{itemize}
+Lorsqu'on transfère la possession, il faut parfois déplacer des valeurs. Tout ce qui est stocké
+sur la pile sera copié à sa nouvelle position. Ce qui est stocké sur le tas restera inchangé.
 
 \begin{lstlisting}[style=Rust, language=Rust]
 fn main() {
-    // Deep copy : \textbf{var2} va copier la valeur de \textbf{var1}
-    let var1 = 12;
-    let var2 = var1;
+    // Ici le déplacement va engendrer une copie profonde de \textbf{var}
+    let var = [1, 2, 3, 4, 5];  // le tableau est stocké sur la pile
+    transfer(var);  // on transfère la possession
+}
 
-    println!("{}", var1);   // "12"
+fn transfer(v: [usize; 5]) {
+    // v a été déplacé vers sa nouvelle position sur la pile
 }
 \end{lstlisting}
-
 \begin{lstlisting}[style=Rust, language=Rust]
 fn main() {
-    // Shallow copy : \textbf{var2} va prendre l'appartenance sur \textbf{var1}
-    let var1 = String::from("Hello world");
-    let var2 = var1;
-
-    // \textbf{var1} est donc devenue invalide.
+    // Cette fois la copie de \textbf{var} sera seulement en surface
+    let var = vec![1, 2, 3, 4, 5];  // le tableau est stocké sur le tas
+    transfer(var);  // on transfère la possession
+}
 
-    println!("{}", var1);   // Erreur de compilation : Utilisation d'une valeur déplacée.
+fn transfer(v: Vec<usize>) {
+    // une nouvelle valeur a été créée sur la pile,
+    // elle pointe vers la même addresse dans le tas qu'avant le transfert de possession
 }
 \end{lstlisting}
 
 
+Parfois on veut vraiment dupliquer une valeur : on a besoin d'une copie
+parce qu'on va modifier la valeur mais on veut se souvenir de l'original.
+
+Pour cela on dispose des traits \texttt{Clone} et \texttt{Copy}.
+Si un objet implémente \texttt{Clone} on peut en créer une copie indépendante
+avec \texttt{.clone()}. \texttt{Copy} fait la même chose mais de manière implicite.
+
+Pour ne pas avoir de mauvaise surprise de performance on n'implémente \texttt{Copy}
+que pour les objets dont la copie ne coûte presque rien.
+\begin{lstlisting}[style=Rust, language=Rust]
+#[derive(Clone)]  // demande au compilateur de générer automatiquement .clone() pour Gros
+struct Gros([usize; 100]);
+
+#[derive(Clone, Copy)] // ici on se permet de rajouter Copy
+                       // parce qu'on sait que dupliquer
+                       // trois valeurs sera très rapide
+struct Petit([usize; 3]);
+
+fn main() {
+    let gros1 = Gros([0; 100]);
+    let mut gros2 = gros1.clone();  // valeur dupliquée explicitement
+    gros2.0[0] = 1;
+    println!("{} != {}", gros1.0[0], gros2.0[0]);
+    // "0 != 1"
+
+    let petit1 = Petit([0; 3]);
+    let mut petit2 = petit1;  // valeur dupliquée implicitement
+    petit2.0[0] = 1;
+    println!("{} != {}", petit1.0[0], petit2.0[0]);
+    // "0 != 1"
+}
+\end{lstlisting}
+Note: des fois un type n'implémente \textit{pas} \texttt{Clone} parce que pouvoir
+en créer une copie serait dangereux. Il n'y a pas besoin de s'en soucier pour nos
+types personnels : si \texttt{\#[derive(Clone)]} réussit c'est que la copie ne
+pose pas de souci.
+
+% HERE
 
 \section{Modularité}
 
@@ -1562,6 +1600,12 @@ struct User {
 \subsection{Tout est une expression}
 \label{expressionsEverywhere}
 
+\subsection{Newtype}
+\label{patternNewtype}
+
+\subsection{Builder}
+\label{patternBuilder}
+
 \subsection{Déstructuration}
 \label{advancedDestructuring}
 
@@ -1574,6 +1618,9 @@ struct User {
 \subsection{Lifetimes}
 \label{advancedLifetimes}
 
+\subsection{Traits}
+\label{advancedTraits}
+
 \subsection{Conteneurs}
 
 Les conteneurs sont des structures permettant de stocker des données.