diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 0f74413096a2aab373b5b70ad4a56ae026522676..259a4c7b7c82da53fec4a7bf06511c347cb0f821 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -13,3 +13,4 @@ include:
   - local: "/a-brief-history-of-date/.gitlab-ci.yml"
   - local: "/mustache-replacer/.gitlab-ci.yml"
   - local: "/string-calculator-2/.gitlab-ci.yml"
+  - local: "/trip-service-kata/.gitlab-ci.yml"
diff --git a/README.md b/README.md
index c0518543dd04625352f8f29a5d7700d48dae19a9..ba030d4a992f34a7593f59045988cc7ec3b29e8d 100644
--- a/README.md
+++ b/README.md
@@ -31,5 +31,6 @@ Ce dépôt Git a pour but de partager les différents ateliers pouvant être ré
 | [Une annonce pour recruter un crafter - Caroline, Chloé, Ianic et Colin](https://www.youtube.com/watch?v=E5AX6Ar1Fog) | Discussion  |            |
 | [PadBowl](https://gitlab.com/cdamon/padbowl)                                                                          | Application | Enervé     |
 | [A Brief History of Date](/a-brief-history-of-date)                                                                   | Kata        | Moyenne    |
+| [Trip service (Java)](/trip-service-kata)                                                                             | Kata        | Moyenne    |
 | [Mustache Replacer](/mustache-replacer)                                                                               | Kata        | Facile     |
 | [String calculator 2](/string-calculator-2)                                                                           | Kata        | Moyenne    |
diff --git a/package-lock.json b/package-lock.json
index 6f96882feeb70c1c00ad62c81065fe1f052778be..b4fba44d02d2c5e9cd732c0cc687824682a0f410 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4,6 +4,18 @@
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
+    "@blakeembrey/deque": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/@blakeembrey/deque/-/deque-1.0.5.tgz",
+      "integrity": "sha512-6xnwtvp9DY1EINIKdTfvfeAtCYw4OqBZJhtiqkT3ivjnEfa25VQ3TsKvaFfKm8MyGIEfE95qLe+bNEt3nB0Ylg==",
+      "dev": true
+    },
+    "@blakeembrey/template": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@blakeembrey/template/-/template-1.0.0.tgz",
+      "integrity": "sha512-J6WGZqCLdRMHUkyRG6fBSIFJ0rL60/nsQNh5rQvsYZ5u0PsKw6XQcJcA3DWvd9cN3j/IQx5yB1fexhCafwwUUw==",
+      "dev": true
+    },
     "@iamstarkov/listr-update-renderer": {
       "version": "0.4.1",
       "resolved": "https://registry.npmjs.org/@iamstarkov/listr-update-renderer/-/listr-update-renderer-0.4.1.tgz",
@@ -111,6 +123,22 @@
       "integrity": "sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog==",
       "dev": true
     },
+    "anymatch": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
+      "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
+      "dev": true,
+      "requires": {
+        "normalize-path": "^3.0.0",
+        "picomatch": "^2.0.4"
+      }
+    },
+    "arg": {
+      "version": "4.1.3",
+      "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
+      "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
+      "dev": true
+    },
     "argparse": {
       "version": "1.0.10",
       "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
@@ -238,6 +266,12 @@
         }
       }
     },
+    "binary-extensions": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz",
+      "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==",
+      "dev": true
+    },
     "brace-expansion": {
       "version": "1.1.11",
       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -340,6 +374,57 @@
         "regexp-to-ast": "0.4.0"
       }
     },
+    "chokidar": {
+      "version": "3.4.3",
+      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz",
+      "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==",
+      "dev": true,
+      "requires": {
+        "anymatch": "~3.1.1",
+        "braces": "~3.0.2",
+        "fsevents": "~2.1.2",
+        "glob-parent": "~5.1.0",
+        "is-binary-path": "~2.1.0",
+        "is-glob": "~4.0.1",
+        "normalize-path": "~3.0.0",
+        "readdirp": "~3.5.0"
+      },
+      "dependencies": {
+        "braces": {
+          "version": "3.0.2",
+          "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+          "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+          "dev": true,
+          "requires": {
+            "fill-range": "^7.0.1"
+          }
+        },
+        "fill-range": {
+          "version": "7.0.1",
+          "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+          "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+          "dev": true,
+          "requires": {
+            "to-regex-range": "^5.0.1"
+          }
+        },
+        "is-number": {
+          "version": "7.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+          "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+          "dev": true
+        },
+        "to-regex-range": {
+          "version": "5.0.1",
+          "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+          "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+          "dev": true,
+          "requires": {
+            "is-number": "^7.0.0"
+          }
+        }
+      }
+    },
     "class-utils": {
       "version": "0.3.6",
       "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
@@ -839,6 +924,13 @@
       "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
       "dev": true
     },
+    "fsevents": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
+      "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
+      "dev": true,
+      "optional": true
+    },
     "g-status": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/g-status/-/g-status-2.0.2.tgz",
@@ -891,6 +983,15 @@
         "path-is-absolute": "^1.0.0"
       }
     },
+    "glob-parent": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
+      "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
+      "dev": true,
+      "requires": {
+        "is-glob": "^4.0.1"
+      }
+    },
     "has-ansi": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
@@ -1014,6 +1115,12 @@
         }
       }
     },
+    "ignore": {
+      "version": "5.1.8",
+      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
+      "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==",
+      "dev": true
+    },
     "import-fresh": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz",
@@ -1066,6 +1173,15 @@
       "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
       "dev": true
     },
+    "is-binary-path": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+      "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+      "dev": true,
+      "requires": {
+        "binary-extensions": "^2.0.0"
+      }
+    },
     "is-buffer": {
       "version": "1.1.6",
       "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
@@ -1725,6 +1841,12 @@
         }
       }
     },
+    "normalize-path": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+      "dev": true
+    },
     "npm-path": {
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/npm-path/-/npm-path-2.0.4.tgz",
@@ -1824,6 +1946,64 @@
         "wrappy": "1"
       }
     },
+    "onchange": {
+      "version": "7.0.2",
+      "resolved": "https://registry.npmjs.org/onchange/-/onchange-7.0.2.tgz",
+      "integrity": "sha512-pyJroR9gZKilbJtdGsuyxhFhwaeYSpYVle9hAORGJ5vQQH8n7QT+qWpncJTMEk9dlIXI9tOMjdJwbPaTSPTKFA==",
+      "dev": true,
+      "requires": {
+        "@blakeembrey/deque": "^1.0.5",
+        "@blakeembrey/template": "^1.0.0",
+        "arg": "^4.1.3",
+        "chokidar": "^3.3.1",
+        "cross-spawn": "^7.0.1",
+        "ignore": "^5.1.4",
+        "tree-kill": "^1.2.2"
+      },
+      "dependencies": {
+        "cross-spawn": {
+          "version": "7.0.3",
+          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+          "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+          "dev": true,
+          "requires": {
+            "path-key": "^3.1.0",
+            "shebang-command": "^2.0.0",
+            "which": "^2.0.1"
+          }
+        },
+        "path-key": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+          "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+          "dev": true
+        },
+        "shebang-command": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+          "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+          "dev": true,
+          "requires": {
+            "shebang-regex": "^3.0.0"
+          }
+        },
+        "shebang-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+          "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+          "dev": true
+        },
+        "which": {
+          "version": "2.0.2",
+          "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+          "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+          "dev": true,
+          "requires": {
+            "isexe": "^2.0.0"
+          }
+        }
+      }
+    },
     "onetime": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
@@ -1899,6 +2079,12 @@
       "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
       "dev": true
     },
+    "picomatch": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
+      "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
+      "dev": true
+    },
     "pinkie": {
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
@@ -1979,6 +2165,15 @@
         "once": "^1.3.1"
       }
     },
+    "readdirp": {
+      "version": "3.5.0",
+      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz",
+      "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==",
+      "dev": true,
+      "requires": {
+        "picomatch": "^2.2.1"
+      }
+    },
     "regex-not": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
@@ -2457,6 +2652,12 @@
         "repeat-string": "^1.6.1"
       }
     },
+    "tree-kill": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
+      "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
+      "dev": true
+    },
     "tslib": {
       "version": "1.13.0",
       "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz",
diff --git a/package.json b/package.json
index 6b18248441786eebc7aa5f314b9166b60cdedf67..c66160c0553937e231688b21de3a2596cfa02602 100644
--- a/package.json
+++ b/package.json
@@ -10,6 +10,7 @@
   "devDependencies": {
     "husky": "1.3.1",
     "lint-staged": "8.1.4",
+    "onchange": "^7.0.2",
     "prettier": "^1.19.1",
     "prettier-plugin-java": "^0.6.0"
   },
diff --git a/trip-service-kata/.gitlab-ci.yml b/trip-service-kata/.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..da8e9b1b31dae37e42f61c93d3d121589d98b6c4
--- /dev/null
+++ b/trip-service-kata/.gitlab-ci.yml
@@ -0,0 +1,11 @@
+package-trip-service-kata:
+  variables:
+    PROJECT_FOLDER: "trip-service-kata"
+  extends: .java
+  only:
+    refs:
+      - master
+      - merge_requests
+    changes:
+      - ".gitlab-common-ci.yml"
+      - "trip-service-kata/**/*"
diff --git a/trip-service-kata/pom.xml b/trip-service-kata/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..15e6a48e31b8e799cef1b08460ee2cb571c85337
--- /dev/null
+++ b/trip-service-kata/pom.xml
@@ -0,0 +1,36 @@
+<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/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <version>1.0.0</version>
+        <groupId>fr.ippon.kata</groupId>
+        <artifactId>java-parent</artifactId>
+        <relativePath>../java-parent</relativePath>
+    </parent>
+
+    <version>1.0.0-SNAPSHOT</version>
+    <artifactId>trip-service-kata</artifactId>
+
+    <name>TripServiceKata</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-engine</artifactId>
+            <version>5.7.0-M1</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <developers>
+        <developer>
+            <email>jlhermite@ippon.fr</email>
+            <name>Julien LHERMITE</name>
+        </developer>
+        <developer>
+            <email>cdamon@ippon.fr</email>
+            <name>Colin DAMON</name>
+        </developer>
+    </developers>
+</project>
diff --git a/trip-service-kata/readme.md b/trip-service-kata/readme.md
new file mode 100644
index 0000000000000000000000000000000000000000..2b12a4e6d6acdc6cfccca220bedb5ab3c3d57ea9
--- /dev/null
+++ b/trip-service-kata/readme.md
@@ -0,0 +1,32 @@
+# Trip service (java)
+
+Découverte et résolution du kata [TripService](https://github.com/sandromancuso/trip-service-kata)
+
+-   **Auteur** : Julien LHERMITE et Colin DAMON
+-   **Date** : 20/10/2020
+-   **Langage** : Java
+-   **Niveau** : Moyen
+-   **Replay** : [Trip Service Kata (Java) avec Julien & Colin](https://www.youtube.com/watch?v=YIKI_-xqJfc)
+
+# Testing legacy code: Hard-wired dependencies
+
+Code related to my [Testing legacy code: Hard-wired dependencies][1] blog post. Try not reading the blog post before doing the exercise yourself.
+
+## What is it about?
+
+Provides an example of existing code that needs to be unit tested. But there is one rule:
+
+> We can't change any existing code if not covered by tests. The only exception is if we need to change the code to add unit tests, but in this case, just automated refactorings (via IDE) are allowed.
+
+Although this is a very small piece of code, it has a lot of the problems that we find in legacy code.
+
+## Details
+
+If you want to give it a go, the starting point is [TripServiceTest.java][3] and [TripService.java][4]. Try unit testing it following the rule above.
+
+For future comparisions, when you are done, you can always check [TripService_Original.java][2]
+
+[1]: http://codurance.com/2011/07/16/testing-legacy-hard-wired-dependencies/ "Testing legacy code: Hard-wired dependencies blog post"
+[2]: https://github.com/sandromancuso/trip-service-kata/blob/master/java/trip-service-kata/src/main/java/org/craftedsw/tripservicekata/TripService_Original.java "TripService_Original.java"
+[3]: https://github.com/sandromancuso/trip-service-kata/blob/master/java/trip-service-kata/src/test/java/org/craftedsw/tripservicekata/TripServiceTest.java "TripServiceTest.java"
+[4]: https://github.com/sandromancuso/trip-service-kata/blob/master/java/trip-service-kata/src/main/java/org/craftedsw/tripservicekata/trip/TripService.java "TripService.java"
diff --git a/trip-service-kata/src/main/java/org/craftedsw/tripservicekata/TripService_Original.java b/trip-service-kata/src/main/java/org/craftedsw/tripservicekata/TripService_Original.java
new file mode 100644
index 0000000000000000000000000000000000000000..a2ba5ee3c2090f4144e631dd8d83ef1b512dd0fe
--- /dev/null
+++ b/trip-service-kata/src/main/java/org/craftedsw/tripservicekata/TripService_Original.java
@@ -0,0 +1,34 @@
+package org.craftedsw.tripservicekata;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.craftedsw.tripservicekata.exception.UserNotLoggedInException;
+import org.craftedsw.tripservicekata.trip.Trip;
+import org.craftedsw.tripservicekata.trip.TripDAO;
+import org.craftedsw.tripservicekata.user.User;
+import org.craftedsw.tripservicekata.user.UserSession;
+
+public class TripService_Original {
+
+	public List<Trip> getTripsByUser(User user) throws UserNotLoggedInException {
+		List<Trip> tripList = new ArrayList<Trip>();
+		User loggedUser = UserSession.getInstance().getLoggedUser();
+		boolean isFriend = false;
+		if (loggedUser != null) {
+			for (User friend : user.getFriends()) {
+				if (friend.equals(loggedUser)) {
+					isFriend = true;
+					break;
+				}
+			}
+			if (isFriend) {
+				tripList = TripDAO.findTripsByUser(user);
+			}
+			return tripList;
+		} else {
+			throw new UserNotLoggedInException();
+		}
+	}
+	
+}
diff --git a/trip-service-kata/src/main/java/org/craftedsw/tripservicekata/exception/CollaboratorCallException.java b/trip-service-kata/src/main/java/org/craftedsw/tripservicekata/exception/CollaboratorCallException.java
new file mode 100644
index 0000000000000000000000000000000000000000..828353e7da1ceee8e506e1e3cd2768d37c89bd83
--- /dev/null
+++ b/trip-service-kata/src/main/java/org/craftedsw/tripservicekata/exception/CollaboratorCallException.java
@@ -0,0 +1,25 @@
+package org.craftedsw.tripservicekata.exception;
+
+public class CollaboratorCallException extends RuntimeException {
+
+	private static final long serialVersionUID = -4584041339906109902L;
+
+	public CollaboratorCallException() {
+		super();
+	}
+
+	public CollaboratorCallException(String message,
+			Throwable cause) {
+		super(message, cause);
+	}
+
+	public CollaboratorCallException(String message) {
+		super(message);
+	}
+
+	public CollaboratorCallException(Throwable cause) {
+		super(cause);
+	}
+
+	
+}
diff --git a/trip-service-kata/src/main/java/org/craftedsw/tripservicekata/exception/UserNotLoggedInException.java b/trip-service-kata/src/main/java/org/craftedsw/tripservicekata/exception/UserNotLoggedInException.java
new file mode 100644
index 0000000000000000000000000000000000000000..880bf2041e5d18c92a58447891c69e2c09b4332b
--- /dev/null
+++ b/trip-service-kata/src/main/java/org/craftedsw/tripservicekata/exception/UserNotLoggedInException.java
@@ -0,0 +1,7 @@
+package org.craftedsw.tripservicekata.exception;
+
+public class UserNotLoggedInException extends RuntimeException {
+
+	private static final long serialVersionUID = 8959479918185637340L;
+
+}
diff --git a/trip-service-kata/src/main/java/org/craftedsw/tripservicekata/trip/Trip.java b/trip-service-kata/src/main/java/org/craftedsw/tripservicekata/trip/Trip.java
new file mode 100644
index 0000000000000000000000000000000000000000..f12ff3cc1e04fe37585e6f1e66cb32fe56f1b671
--- /dev/null
+++ b/trip-service-kata/src/main/java/org/craftedsw/tripservicekata/trip/Trip.java
@@ -0,0 +1,5 @@
+package org.craftedsw.tripservicekata.trip;
+
+public class Trip {
+
+}
diff --git a/trip-service-kata/src/main/java/org/craftedsw/tripservicekata/trip/TripDAO.java b/trip-service-kata/src/main/java/org/craftedsw/tripservicekata/trip/TripDAO.java
new file mode 100644
index 0000000000000000000000000000000000000000..8c5c5d4db5efa684f00b4724f8dda72c1c5d22d4
--- /dev/null
+++ b/trip-service-kata/src/main/java/org/craftedsw/tripservicekata/trip/TripDAO.java
@@ -0,0 +1,17 @@
+package org.craftedsw.tripservicekata.trip;
+
+import java.util.List;
+import org.craftedsw.tripservicekata.exception.CollaboratorCallException;
+import org.craftedsw.tripservicekata.user.User;
+
+public class TripDAO implements Trips {
+
+  public static List<Trip> findTripsByUser(User user) {
+    throw new CollaboratorCallException("TripDAO should not be invoked on an unit test.");
+  }
+
+  @Override
+  public List<Trip> find(User user) {
+    return TripDAO.findTripsByUser(user);
+  }
+}
diff --git a/trip-service-kata/src/main/java/org/craftedsw/tripservicekata/trip/TripService.java b/trip-service-kata/src/main/java/org/craftedsw/tripservicekata/trip/TripService.java
new file mode 100644
index 0000000000000000000000000000000000000000..00ea28839617bcfa939a4a015b61e616ef39d500
--- /dev/null
+++ b/trip-service-kata/src/main/java/org/craftedsw/tripservicekata/trip/TripService.java
@@ -0,0 +1,39 @@
+package org.craftedsw.tripservicekata.trip;
+
+import java.util.List;
+import org.craftedsw.tripservicekata.exception.UserNotLoggedInException;
+import org.craftedsw.tripservicekata.user.User;
+import org.craftedsw.tripservicekata.user.UserSession;
+
+public class TripService {
+  private final UserSession userSession;
+  private final Trips trips;
+
+  public TripService(UserSession userSession, Trips trips) {
+    this.userSession = userSession;
+    this.trips = trips;
+  }
+
+  public List<Trip> getTripsByUser(User user) throws UserNotLoggedInException {
+    User loggedUser = userSession.getLoggedUser();
+    assertUserIsAuthenticated(loggedUser);
+
+    return user
+      .getFriends()
+      .stream()
+      .filter(friend -> friend.equals(loggedUser))
+      .findFirst()
+      .map(friend -> findTrips(user))
+      .orElse(List.of());
+  }
+
+  protected List<Trip> findTrips(User user) {
+    return trips.find(user);
+  }
+
+  private void assertUserIsAuthenticated(User loggedUser) {
+    if (loggedUser == null) {
+      throw new UserNotLoggedInException();
+    }
+  }
+}
diff --git a/trip-service-kata/src/main/java/org/craftedsw/tripservicekata/trip/Trips.java b/trip-service-kata/src/main/java/org/craftedsw/tripservicekata/trip/Trips.java
new file mode 100644
index 0000000000000000000000000000000000000000..66e97d16cce8fea5ce281bd67fcb1917d24168fa
--- /dev/null
+++ b/trip-service-kata/src/main/java/org/craftedsw/tripservicekata/trip/Trips.java
@@ -0,0 +1,8 @@
+package org.craftedsw.tripservicekata.trip;
+
+import java.util.List;
+import org.craftedsw.tripservicekata.user.User;
+
+public interface Trips {
+  List<Trip> find(User user);
+}
diff --git a/trip-service-kata/src/main/java/org/craftedsw/tripservicekata/user/User.java b/trip-service-kata/src/main/java/org/craftedsw/tripservicekata/user/User.java
new file mode 100644
index 0000000000000000000000000000000000000000..cafaa2002326d83f4052f4e8776907299ac58b04
--- /dev/null
+++ b/trip-service-kata/src/main/java/org/craftedsw/tripservicekata/user/User.java
@@ -0,0 +1,29 @@
+package org.craftedsw.tripservicekata.user;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.craftedsw.tripservicekata.trip.Trip;
+
+public class User {
+
+	private List<Trip> trips = new ArrayList<Trip>();
+	private List<User> friends = new ArrayList<User>();
+	
+	public List<User> getFriends() {
+		return friends;
+	}
+	
+	public void addFriend(User user) {
+		friends.add(user);
+	}
+
+	public void addTrip(Trip trip) {
+		trips.add(trip);
+	}
+	
+	public List<Trip> trips() {
+		return trips;
+	}
+
+}
diff --git a/trip-service-kata/src/main/java/org/craftedsw/tripservicekata/user/UserSession.java b/trip-service-kata/src/main/java/org/craftedsw/tripservicekata/user/UserSession.java
new file mode 100644
index 0000000000000000000000000000000000000000..6b91c0d86ef6e8ca6ad541010ce0816eaf9528de
--- /dev/null
+++ b/trip-service-kata/src/main/java/org/craftedsw/tripservicekata/user/UserSession.java
@@ -0,0 +1,21 @@
+package org.craftedsw.tripservicekata.user;
+
+import org.craftedsw.tripservicekata.exception.CollaboratorCallException;
+
+public class UserSession {
+
+	private static final UserSession userSession = new UserSession();
+	
+	private UserSession() {
+	}
+	
+	public static UserSession getInstance() {
+		return userSession;
+	}
+
+	public User getLoggedUser() {
+		throw new CollaboratorCallException(
+				"UserSession.getLoggedUser() should not be called in an unit test");
+	}
+
+}
diff --git a/trip-service-kata/src/test/java/org/craftedsw/tripservicekata/trip/TripDAOTest.java b/trip-service-kata/src/test/java/org/craftedsw/tripservicekata/trip/TripDAOTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..36f1e09ddbdfbf96bd70faab49f1309f5ea9d451
--- /dev/null
+++ b/trip-service-kata/src/test/java/org/craftedsw/tripservicekata/trip/TripDAOTest.java
@@ -0,0 +1,3 @@
+package org.craftedsw.tripservicekata.trip;
+
+class TripDAOTest {}
diff --git a/trip-service-kata/src/test/java/org/craftedsw/tripservicekata/trip/TripServiceTest.java b/trip-service-kata/src/test/java/org/craftedsw/tripservicekata/trip/TripServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..f22c19907cc874638a191d099253a5c63f4ae43e
--- /dev/null
+++ b/trip-service-kata/src/test/java/org/craftedsw/tripservicekata/trip/TripServiceTest.java
@@ -0,0 +1,61 @@
+package org.craftedsw.tripservicekata.trip;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.Mockito.when;
+
+import java.util.List;
+import org.craftedsw.tripservicekata.exception.UserNotLoggedInException;
+import org.craftedsw.tripservicekata.user.User;
+import org.craftedsw.tripservicekata.user.UserSession;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+@ExtendWith(MockitoExtension.class)
+class TripServiceTest {
+  private final User authenticatedUser = new User();
+
+  private final User friend = new User();
+
+  @Mock
+  private UserSession userSession;
+
+  @Mock
+  private Trips trips;
+
+  @InjectMocks
+  private TripService service;
+
+  @BeforeEach
+  void loadAuthentication() {
+    when(userSession.getLoggedUser()).thenReturn(authenticatedUser);
+  }
+
+  @Test
+  void shouldNotGetTripsWithoutAuthenticatedUser() {
+    when(userSession.getLoggedUser()).thenReturn(null);
+
+    assertThatThrownBy(() -> service.getTripsByUser(authenticatedUser)).isExactlyInstanceOf(UserNotLoggedInException.class);
+  }
+
+  @Test
+  void shouldGetEmptyTripsForNewUser() {
+    assertThat(service.getTripsByUser(authenticatedUser)).isEmpty();
+  }
+
+  @Test
+  void shouldGetFriendTrips() {
+    friend.addFriend(authenticatedUser);
+
+    Trip tripToLasVegas = new Trip();
+    friend.addTrip(tripToLasVegas);
+
+    when(trips.find(friend)).thenReturn(List.of(tripToLasVegas));
+
+    assertThat(service.getTripsByUser(friend)).containsExactly(tripToLasVegas);
+  }
+}