You've reached the end of this Advanced Programming in Kotlin course, well done. You've come a long way to learn new skills, added more tools to your development toolbox and expanded your understanding of the Kotlin programming language. Take a moment to congratulate yourself, after all, you've learned a lot in this course. The end of course, graded assessment is a development project where you will get a chance to apply what you've learned. This includes integrating Kotlin and android using advanced object-oriented features and implementing functional programming. But before you embark on the final assessment, let's reflect on the key learning milestones you've reached. You began this course with an examination of Android and Kotlin in the real world, and you covered the steps to set up an Android project in Kotlin. The major new learning area for you in Week 2 concerned object declarations. You specifically learned about object declarations as well as constant values and activities with arguments. You discovered the concept called singleton, where you create only one instance of a class, to do this in Kotlin, you can use an object declaration. And finally, you learned how to implement constant values and functions with arguments in companion objects. You then explored the advanced object-oriented features of code development. Major items you covered here included using an extension function to add a method to a class, exploring test-driven development including its methodology and main features. Discovering the purpose and types of testing and implementing a unit test, employing mocks and fakes for unit testing in Android and defining and using a generic class. You learned what extension functions are, why you need them, and what their limitations are. You use extension functions whenever you have to extend the functionality of a class or an interface in an external or a third-party library that you cannot inherit from or modify. Testing was a major topic to cover, and you should now know why testing is an essential part of software development, it ensures your software works as expected. Testing comes in two main types, functional testing and non-functional testing. Several advantages of a test-driven development were mentioned, including you write minimal code with the intent of passing all the defined tests. Your code is highly tested and has a high test coverage, and it is easier to maintain and refactor code. However, there are certain dangers with test-driven development or TDD, these include simply writing unit tests alone is not sufficient in this environment. Following TDD strictly may require an excessive amount of testing time, false positives may arrive when developers incorrectly assume expected outcomes and the practice of TDD can be hard to adapt to. You covered collections in Kotlin, a collection in Kotlin is used to represent a group of related objects or elements that can be referenced as a single unit perhaps using a variable. Kotlin allows you to access elements in a collection independent of the exact type of objects or elements stored in a collection. This is achieved using the collection interface which is inherited by all subtypes of collections such as lists, sets or maps. Generics have particular advantages in Kotlin, including type safety, compile time checking, and no need for typecasting. In the following week, you learned about using a Lambda expression. A lambda expression refers to passing the function implementation as an expression and is enclosed within curly braces. In Week 3, you learned about using a lambda expression. A lambda expression refers to passing the function implementation as an expression and is enclosed within curly braces. You then moved on to higher-order functions. A higher-order function is a function that has other functions as its parameter or return value. Having a function or a lambda as an argument of another function allows you to delegate a part of its responsibilities to the argument function. Therefore, the scope of tasks handled by a single function is reduced. Also, this enables you to customize the use case of each function execution without overloading it with if else or when statements. Lastly, you learned about the collection processing functions. Collection processing involves three primary steps, accessing elements of a collection on which the operations to be applied, defining and applying the operation on the element and outputting a modified collection with the updated or transformed elements. You learned about the importance of collection processing and explored some examples of common operations that can be applied to elements in a collection. As an example of collection processing in action, you implemented different operations on their own and as part of multistep collection processing that included defining and using forEach, map, filter and fold. You've reached the end of this course recap, it's now time for you to proceed to the last part of your course and try out what you've learned in the grated assessment. Good luck with that final practical app project for the Little Lemon Restaurant.