+- Открыть и настроить проект в IDEA
+ - Выставить кодировку UTF-8 в консоли
+ - Поставить кодировку UTF-8
+ - Поменять фонт по умолчанию (DejaVu)
+- По ходу видео сделать Apply Patch... скаченного патча Prepare_ to_ HW0.patch
+- Закоммитить и запушить изменения (commit + push)
+- Сделать ветку домашнего задания
+- Выполнить задание и залить на GitHub (commit + push)
+- Переключиться в основную ветку проекта master.
+
+##  Домашнее задание HW0
+```
+Реализовать метод UserMealsUtil.getFilteredWithExceeded:
+- должны возвращаться только записи между startTime и endTime
+- поле UserMealWithExceed.exceed должно показывать,
+ превышает ли сумма калорий за весь день параметра метода caloriesPerDay
+
+Т.е UserMealWithExceed - это запись одной еды, но поле exceeded будет одинаково для всех записей за этот день.
+
+- Проверте результат выполнения ДЗ (можно проверить логику в http://topjava.herokuapp.com , список еды)
+- Оцените Time complexity вашего алгоритма, если он O(N*N)- попробуйте сделать O(N).
+```
+- Java 8 Date and Time API
+- Алгоритмы и структуры данных для начинающих: сложность алгоритмов
+- Time complexity
+- Временная сложность алгоритма
+- Вычислительная сложность
+
+#### Optional (Java 8 Stream API)
+```
+Сделать реализация через Java 8 Stream API.
+```
+- Видео: Доступно о Java 8 Lambda
+- Java 8: Lambda выражения
+- Java 8: Потоки
+- Pуководство по Java 8 Stream
+- Лямбда-выражения в Java 8
+- A Guide to Java 8
+- Шпаргалка Java Stream API
+- Алексея Владыкин: Элементы функционального программирования в Java
+- Yakov Fain о новом в Java 8
+- stream.map vs forEach
+- Дополнительно
+ - [Сергей Куксенко — Stream API, часть 1](https://www.youtube.com/watch?v=O8oN4KSZEXE)
+ - [Сергей Куксенко — Stream API, часть 2](https://www.youtube.com/watch?v=i0Jr2l3jrDA)
+
+#### Optional 2 (+5 бонусов)
+```
+Сделать реализацию со сложностью O(N):
+- циклом за 1 проход по List. Обратите внимание на п.13 замечаний
+- через Stream API за 1 проход по Stream
+```
+#### Замечания по использованию Stream API:
+- Когда встречаешь что-то непривычное, приходится перестраивать мозги. Например переход с процедурного на ООП программирование дается непросто. Те, кто не знает шаблонов (и не хоят учить) также их встречают плохо. Хорошая новость в том, что если это принять и начать использовать, то начинаешь получать от этого удовольствие. И тут главное не впасть в другую крайность:
+ - [Используйте Stream API проще (или не используйте вообще)](https://habrahabr.ru/post/337350/)
+- Если вас беспокоить производительность стримов, обязательно прочитайте про оптимизацию
+ - ["Что? Где? Когда?"](http://optimization.guide/intro.html)
+ - [Перформанс: что в имени тебе моём?](https://habrahabr.ru/company/jugru/blog/338732/)
+ - [Performance это праздник](https://habrahabr.ru/post/326242/)
+
+При использовании Stream API производительность улучшиться только на больших задачах, где возможно распараллеливание.
+Еще - просто так запустить и померять скорость JVM нельзя (как минимум дать прогреться и запустить очень большое число раз). Лучше использовать какие-нибудь бенчмарки, например [JMH](http://tutorials.jenkov.com/java-performance/jmh.html), который мы юзаем на другом проекте (Mastejava).
+
+##  Замечания к HW0
+- 1: Код проекта менять можно! Одна из распространенных ошибок как в тестовых заданиях на собеседовании, так и при работе на проекте, что ничего нельзя менять. Конечно при правках в рабочем проекте обязятельно нужно проконсультироваться/проревьюится у авторов кода (находится по истории VCS)
+- 2: Наследовать `UserMealWithExceed` от `UserMeal` я не буду, т.к. это разные сущности: Transfer Object и Entity. Мы будет их проходить на 2м уроке.
+- 3: Правильная реализация должна быть простой и красивой, можно сделать 2-мя способами: через стримы и через циклы. Сложность должна быть O(N), т.е. без вложенных стримов и циклов.
+- 4: При реализации через циклы посмотрите в `Map` на методы `getOrDefault` или `merge`
+- 5: **При реализации через `Stream` заменяйте `forEach` оператором `stream.map(..)`**
+- 6: Объявляйте переменные непосредственно перед использованием (если возможно - сразу с инициализацией). При объявлении коллекций используйте тип переменной - интерфейс (Map, List, ..)
+- 7: Если IDEA предлагает оптимизацию (желтым подчеркивает), нарпимер заменить лямбду на метод-референс, соглашайтесь (Alt+Enter)
+- 8: Пользуйтесь форматированием кода в IDEA: `Alt+Ctrl+L`
+- 9: Перед check-in проверяйте чендж-лист (курсор на файл и Ctrl+D): не оставляйте в коде ничего лишнего (закомментированный код, TODO и пр.). Если файл не меняется (например только пробелы или переводы строк), не надо его чекинить, делайте ему `revert` (Git -> Revert / `Ctrl+Alt+Z`).
+- 10: `System.out.println` нельзя делать нигде, кроме как в `main`. Позже введем логирование.
+- 11: Результаты, возвращаемые `UserMealsUtil.getFilteredWithExceeded` мы будем использовать [в нашем приложении](http://topjava.herokuapp.com/) для фильтрации по времени и отображения еды правильным цветом.
+- 12: Обращайте внимание на комментарии к вашим коммитам в git. Они должны быть короткие и информативные (лучше на english)
+- 13: Не полагайтесь в решениии на то, что список будет подаваться отсортированным. Такого условия нет.
+-----
+
+### Полезные ресурсы
+> ВНИМАНИЕ:
+> - ДЗ первого урока будет связано с созданием небольшого CRUD приложения (в памяти, без DB) на JSP и сервлетах. Введение будет, но предварительное знакомство не помешает.
+> - основы JavaSсript необходимы для понимания проекта, начиная с 8-го занятия!
+
+Все остальное - опционально.
+
+#### HTML, JavaScript, CSS
+- [Справочник по WEB](https://developer.mozilla.org/ru/)
+- [Видео по WEB технологиям](https://www.youtube.com/user/WebMagistersRu/playlists)
+- [Изучение JavaScript в одном видео уроке за час](https://www.youtube.com/watch?v=QBWWplFkdzw)
+- HTML, CSS, JAVASCRIPT, SQL, JQUERY, BOOTSTRAP
+- Введение в программирование на JavaScript
+- Стандарты кодирования для HTML, CSS и JavaScript’a
+- Основы работы с HTML/CSS/JavaScript
+- JavaScript - Основы
+- Основы JavaScript
+- Bootstrap 3 - Основы
+- jQuery для начинающих
+
+#### Java (базовые вещи)
+- Интуит. Программирование на Java
+- 1й урок MasterJava: Многопоточность
+- Основы Java garbage collection
+- Размер Java объектов
+- Введение в Java Reflection API
+- Структуры данных в картинках
+- Обзор java.util.concurrent.*
+- Синхронизация потоков
+- String literal pool
+- Маленькие хитрости Java
+- A Guide to Java 8
+
+### Туториалы, разное
+[Что нужно знать о бэкенде новичку в веб-разработке](https://tproger.ru/translations/backend-web-development)
+[Туториалы: Spring Framework, Hibernate, Java Core, JDBC](http://proselyte.net/tutorials/)
+
+#### Сервлеты
+- Как создать Servlet? Полное руководство.
+
+#### JDBC, SQL
+- Основы SQL на примере задачи
+- Уроки по JDBC
+- Learn SQL
+- Интуит. Основы SQL
+- Try SQL
+- Курс "Введение в базы данных"
+
+#### Разное
+- Эффективная работа с кодом в IntelliJ IDEA
+- Quizful- тесты онлайн
+- Введение в Linux
+
+#### Книги
+- Джошуа Блох: Java. Эффективное программирование. Второе издание
+- Гамма, Хелм, Джонсон: Приемы объектно-ориентированного проектирования. Паттерны проектирования
+- Редмонд Э.: Семь баз данных за семь недель. Введение в современные базы данных и идеологию NoSQL
+- Brian Goetz: Java Concurrency in Practice
+- G.L. McDowell: Cracking the Coding Interview
diff --git a/ReleaseNotes.md b/ReleaseNotes.md
new file mode 100644
index 000000000000..9f794333656b
--- /dev/null
+++ b/ReleaseNotes.md
@@ -0,0 +1,142 @@
+# TopJava Release Notes
+### Topjava 12
+- добавилось [видео решений HW0 с одним проходом](https://drive.google.com/open?id=0B9Ye2auQ_NsFcUVfU1hmYUx3Rzg)
+- поправил видео [Обзор Spring Framework. Spring Context](https://drive.google.com/file/d/1fBSLGEbc7YXBbmr_EwEHltCWNW_pUmIH). Дописал про Constructor injection.
+- заменил видео про тетсирование сервисов. Вместо самодельных матчеров стали использовать [AssertJ](http://joel-costigliola.github.io/assertj/index.html). Видео [Тестирование UserService через AssertJ](https://drive.google.com/open?id=1SPMkWMYPvpk9i0TA7ioa-9Sn1EGBtClD), время 1:53
+
+### Topjava 11
+- добавил
+ - доп. решение HW1 через одним return и O(N)
+ - раскрасил лог ([Logback layouts coloring](https://logback.qos.ch/manual/layouts.html#coloring))
+- рефакторинг
+ - починил коммит формы по cancel (`history.back()`) в FireFox
+ - заменил неработающий DependencyCi на [VersionEye](https://www.versioneye.com/) c проверкой зависимостей на uptodate
+ - починил `CrudUserRepository.getWithMeals()` через `@EntityGraph`. С неколькими ролями (у админа) еда дублируется
+ - починил тесты контроллеров с профилем JDBC (`JpaUtil` отсутствует в контексте JDBC)
+ - переименовал `meal.jsp/user.jsp` в `mealForm.jsp/userForm.jsp`
+ - в `InMemoryMealRepositoryImpl.save()` сделал update атомарным
+ - переименовал методы сервисов `save` в `create`
+ - переименовал и cделал классы `BaseEntity` и `NamedEntity` абстрактными
+ - обновил Noty и API с ним до 3.1.0. Добавил glyphicon в сообщения Noty
+ - заменил `MATCHER_WITH_EXCEED` на валидацию через [JSONassert](https://github.com/skyscreamer/JSONassert).
+ - поменял Deprecated валидаторы `org.hibernate.validator.constraints` на `javax.validation.constraints`
+ - убрал пароль из результатов REST через [@JsonProperty READ_ONLY / WRITE_ONLY](https://stackoverflow.com/questions/12505141/only-using-jsonignore-during-serialization-but-not-deserialization/12505165#12505165). Тесты на REST пришлось починить добавлением добавлением в JSON пароля как дополнительного параметра (`JsonUtil.writeWithExtraProps`)
+ - **убрал JSON View и сделал преобразование времени на UI с помощью [jQuery converters](http://api.jquery.com/jQuery.ajax/#using-converters)**
+ - **поменял [группу валидации по умолчанию при сохранении через JPA](https://stackoverflow.com/questions/16930623/16930663#16930663).** Теперь
+ все валидаторы в модели работаю по умолчанию (`groups` не требуется).
+ - Добавил в `ErrorInfo` тип ошибки `ErrorType` + i18n.
+
+- правки
+ - переименовал `ModelMatcher` в `BeanMatcher` и починил: можно сравнивать только упорядоченные коллекции (List)
+ - поменял зависимость `org.hibernate:hibernate-validator` на `org.hibernate.validator:hibernate-validator` (warning при сборке)
+
+### Topjava 10
+- добавил
+ - доступ к AuthorizedUser через [`@AuthenticationPrincipal`](http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#mvc-authentication-principal) и [authentication Tag](http://docs.spring.io/spring-security/site/docs/current/reference/html/taglibs.html#the-authentication-tag)
+ - [Обработку 404 NotFound](https://stackoverflow.com/questions/18322279/spring-mvc-spring-security-and-error-handling)
+ - локализацию ошибок валидации
+ - проверки json в тестах через [JSONassert](https://github.com/skyscreamer/JSONassert) и [через jsonPath](https://www.petrikainulainen.net/programming/spring-framework/integration-testing-of-spring-mvc-applications-write-clean-assertions-with-jsonpath/)
+ - [логирование от Postgres Driver](http://stackoverflow.com/a/43242620/548473)
+ - в `.travis.yml` [сборку только ветки master](https://docs.travis-ci.com/user/customizing-the-build#Building-Specific-Branches)
+ - [защиту от кэширование ajax запросов в IE](https://stackoverflow.com/a/4303862/548473)
+ - обработку запрета модификации системный юзеров через универсальный `ApplicationException`
+ - рефакторинг
+ - сделал `@EntityGraph` через `attributePaths`
+ - реализаовал обработку дублирования `user.email` и `meal.dateTime` через [Controller Based Exception Handling](https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc#controller-based-exception-handling)
+ - поменял отключение транзакционности в тестах через `@Transactional(propagation = Propagation.NEVER)`
+ - сделал выбор в сервлете через switch
+ - [все логгирование сделал через {} форматирование](http://stackoverflow.com/questions/10555409/logger-slf4j-advantages-of-formatting-with-instead-of-string-concatenation) и поправил его в контроллерах (поле проверки id)
+ - [перешел на конструктор DI](http://stackoverflow.com/questions/39890849/what-exactly-is-field-injection-and-how-to-avoid-it)
+ - в `ModelMatcher` переименовал `Comparator` -> `Equality`
+ - [заинлайнил все лямбды](http://stackoverflow.com/questions/19718353/is-repeatedly-instantiating-an-anonymous-class-wasteful) (компараторы, ModelMatcher.equality)
+ - поменялась реализация `JdbcUserRepositoryImpl.getAll()`
+ - на UI кнопки в таблице заменились на линки, поправил сообщения локализации
+ - [сделал кастомизацию JSON (@JsonView) и валидацию (groups)](https://drive.google.com/file/d/0B9Ye2auQ_NsFRTFsTjVHR2dXczA) для данных еды, отдаваемых на UI
+ - в `JdbcUserRepositoryImpl` поменял `MapSqlParameterSource` на `BeanPropertySqlParameterSource`
+- удалил
+ - зависимость `javax.transaction.jta` (уже не нужна)
+ - `${spring.version}` в `pom.xml` зависимостях (уже есть в `spring-framework-bom`)
+ - distinct из запроса Hibernate на пользователей с ролями. [Оптимизация запроса distinct: 15.16.2](https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#hql-distinct)
+ - лишние `
` тэги (`shadow` и `view-box`)
+
+### Topjava 9
+- добавил
+ - выбор профиля базы через `ActiveProfilesResolver`/`AllActiveProfileResolver` на основе драйвера базы в classpath
+ - видео Cascade. Auto generate DDL.
+ - проверку на правильность id в Ajax/Rest контроллерах (treat IDs in REST body)
+ - тесты на валидацию входных значений контроллеров и зависимость на имплементацию
+ - Bootstrap Glyphicons
+- рефакторинг
+ - переименовал `TimeUtil` в `DateTimeUtil`
+ - переименовал `ExceptionUtil` в `ValidationUtil`
+ - заменил валидацию `@NotEmpty` на `@NotBlank`
+ - заменил `CascadeType.REMOVE` на `@OnDelete`
+ - изменил `JdbcUserRepositoryImpl.getAll()`
+ - обновил jQuery до 3.x, исключил из зависимостей webjars ненужные jQuery
+ - cделал загрузку скриптов асинхронной
+ - фильтр еды сделал в [Bootstrap Panels](http://getbootstrap.com/components/#panels)
+ - вместо `Persistable` ввел интерфейс `HasId` и наследую от него как Entity, так и TO
+ - сделал универсальную обработку исключений дублирования email и dateTime
+
+### Topjava 8
+- добавил:
+ - [защиту от XSS (Cross-Site Scripting)](http://stackoverflow.com/a/40644276/548473)
+ - интеграцию с Dependency Ci и Travis Ci
+ - локализацию календаря
+ - сводку по результатам тестов
+ - примеры запросов curl в `config/curl.md`
+ - DataTables/Bootstrap 3 integration
+ - тесты на профиль деплоя Heroku (общее количество JUnit тестов стало 102)
+- удалил зависимость `jul-to-slf4j`
+- рефакторинг
+ - переименовал все классы `UserMeal**` в `Meal**`, JSP
+ - переименовал `LoggedUser` в `AuthorizedUser`
+ - починил работа с PK Hibernate в случае ленивой загрузки (баг HHH-3718)
+ - поменял в `BaseEntity` `equals/hashCode/implements Persistable`
+ - в `InMemoryMealRepositoryImpl` выделил метод `getAllStream`
+ - перенес проверки пердусловий `Assert` из `InMemory` репозиториев в сервисы
+ - переименовал классы _Proxy*_ на более адекватные _Crud*_
+ - поменял реализацию `JpaMealRepositoryImpl.get`, добавил в JPA модель `@BatchSize`
+ - вместо `@RequestMapping` ввел Spring 4.3 аннотации `@Get/Post/...Mapping`
+ - поменял авторизацию в тестах не-REST контроллеров
+ - перенес вызовы `UserUtil.prepareToSave` из `AbstractUserController` в `UserServiceImpl`
+ - зарефакторил обработку ошибок (`ExceptionInfoHandler`)
+
+### Topjava 7
+- добавил:
+ - [JPA 2.1 EntityGraph](https://docs.oracle.com/javaee/7/tutorial/persistence-entitygraphs002.htm)
+ - [Jackson @JsonView](https://habrahabr.ru/post/307392/)
+ - валидацию объектов REST
+ - [i18n в JavaScript](http://stackoverflow.com/a/6242840/548473)
+ - проверку предусловий и видео Методы улучшения качества кода
+ - интеграцию с проверкой кода в Codacy
+ - [сравнение вермени исполнения запросов при различных meals индексах](https://drive.google.com/open?id=0B9Ye2auQ_NsFX3RLcnJCWmQ2Y0U)
+- tomcat7-maven-plugin плагин перключили на Tomcat 8 (cargo-maven2-plugin)
+- рефакторинг
+ - обработка ошибок сделал с array
+ - матчеров тестирования (сделал автоматические обертки и сравнение на основе передаваемого компаратора)
+ - вынес форматирование даты в `functions.tld`
+
+### Topjava 3-6
+- добавил
+ - [выпускной проект](https://drive.google.com/open?id=0B9Ye2auQ_NsFcG83dEVDVTVMamc)
+ - в таблицу meals составной индекс
+ - константы `Profiles.ACTIVE_DB`, `Profiles.DB_IMPLEMENTATION`
+ - проверки и тесты на `NotFound` для `UserMealService.getWithUser` и `UserService.getWithMeals`
+ - в MockMvc фильтр CharacterEncodingFilter
+ - защиту от межсайтовой подделки запроса, видео Межсайтовая подделка запроса (CSRF)
+ - ограничение на диапазон дат для фильтра еды
+- рефакторинг
+ - UserMealsUtil, ProfileRestController, компараторов в репозитоии
+ - `LoggedUser` отнаследовал от `org.springframework.security.core.userdetails.User`
+ - переименовал `DbTest` в `AbstractServiceTest` и перенес сюда `@ActiveProfiles`
+ - сделал выполнение скриптов в тестах через аннотацию `@Sql`
+ - вместо использования id и селектора сделал обработчик `onclick`
+ - изменил формат ввода даты в форме без 'T'
+- убрал
+ - `LoggerWrapper`
+ - Dandelion обертку к datatables
+- обновил
+ - Hibernate до 5.x и Hibernate Validator, добавились новые зависимости и `jackson-datatype-hibernate5`
+ - datatables API (1.10)
+ - Postgres драйвер. Новый драйвер поддерживает Java 8 Time API, разделил реализацию JdbcMealRepositoryImpl на Java8 (Postgresql) и Timestamp (HSQL)
diff --git a/cv.md b/cv.md
new file mode 100644
index 000000000000..4b51e6d7fd8b
--- /dev/null
+++ b/cv.md
@@ -0,0 +1,104 @@
+## Составление резюме, подготовка к интервью, поиск работы
+
+
+
+- Научиться программировать сложнее, чем кажется
+- [Собеседование. Разработка ПО. Вопросы.](https://drive.google.com/open?id=0B9Ye2auQ_NsFQVc2WUdCR0xvLWM)
+- [Набор ссылок для тренировки и прохождения интервью](https://github.com/andreis/interview)
+
+### Составление резюме:
+- [VisualCV: create resume in minutes](https://www.visualcv.com/)
+- Выбрать шаблон для резюме
+- Как продать свое резюме в 2 раза дороже
+- Как правильно составить резюме
+- Резюме программистов. Часть 1 (плохие)
+- Резюме программистов. Часть 2 (хорошие)
+- Как составить резюме на английском
+- ОФОРМЛЕНИЕ IT-РЕЗЮМЕ для USA
+
+### Наши истории (делимся опытом и успехом)
+
+### Тесты/задачи онлайн:
+- [Java Programming Test](https://tests4geeks.com/java)
+- game: test Java skills
+- Codility lesson tests
+- Quizful- тесты онлайн
+- LeetCode Online Judge
+- Sphere online judge
+- Codility programmers lessons
+- Hackerrank practice coding
+
+## [Тестовое собеседование, самые спрашиваемые темы](http://javaops.ru/interview/test.html)
+
+### Интервью:
+- Михаил Портнов. Собеседование на работу: как продать себя грамотно
+- Михаил Портнов. Какие вопросы мы задаем на собеседовании?
+- Михаил Портнов. Собеседование на работу: жизненный путь
+- Канал: Резюме, поиск работы, интервью
+- Яков Файн: Как стать профессиональным Java разработчиком
+- Ответы на вопросы на собеседовании Junior Java Developer
+- Список вопросов с ответами для собеседования по Java
+- Сборка по вопросам на интервью
+- Сборка вопросов-ответов от JavaStudy
+- Тест на знание SQL
+- Вопросы на собеседовании Java Junior Developer
+- Java вопросы с собеседований на Android
+- Сборка вопросов от JavaRush
+> про clone и finalize объязательно прочтите Джошуа Блох: Java. Эффективное программирование (второе издание)
+
+- Cracking the Coding Interview
+> Особенно обратите внимание на раздел: Часть VIII. Вопросы собеседования
+
+
+### От себя:
+- email, skype - очень желательно, чтобы по ним вы были узнаваемы. Заведите рабочие, если не так.
+- написать ВЕСЬ IT опыт (исключая опыт пользователя: Windows, MS Word, Photophop, Yandex disk, Google docs, ..): технологии, какие задачи решали (конкретные), какие инструменты использовали, VCS, DB, инструменты сборки, ... включая опыт в ВУЗе.
+- на English иметь желательно. Если вакансия опублинована на Englsih - шлите на нем. Часто могут на нем попросить, если работодатель иностранный.
+- удобно иметь резюме где то в инете (hh, linkedin, google doc, чтобы им было удобно делиться).
+
+### Позиционирование проекта Topjava:
+- Обязательно убери из резюме **любое упоминание Junior**. Количество обращений возрастет на порядок. Ссылку на стажировку можно поставить: http://javaops.ru (в linkedin: https://www.linkedin.com/company/java-online-projects).
+- После завершения проекта ты освошь все заявленные в нем технологии - вставь их в квалификацию (включая java 8 Stream and Time API).
+- В разделе опыт работы (если нет коммерческого опыта) вставь:
+
+ Участие в разработке Spring/JPA Enterprise приложения c авторизацией и правами доступа на основе ролей
+ на стеке Maven/ Spring MVC/ Security/ REST(Jackson)/ Java 8 Stream API:
+ - реализация сохранения в базы Postgres и HSQLDB на основе Spring JBDC, JPA(Hibernate) и Spring-Data-JPA
+ - реализация и тестирование REST и AJAX контроллеров
+ - реализация клиента на Bootstrap (css/js), datatables, jQuery + plugins.
+ - собственная доработка проекта
+
+- Делай упор не на обучение, а на **участие в проекте**. Выполнение домашних заданий это полноценное участие с написанием функционала по всем пройденным технологиям. На собеседовании смотрят не на то, что ты заканчивал, а на опыт и знания.
+
+### В процессе обучения
+- Если рассмотриваешь предложения по работе, подними в своем профиле этот флаг и обязательно заполни ссылку на резюме. Обновления нашей базы выпускников смотрят уже более 125 партнеров по трудоустройству (компании и индивидуальные рекрутеры). Проверь содержание "Информация для HR": по нему принимают решение, открывать резюме или нет.
+
+- Вступайте в нашу группу участников Slack: каналы помощи с Java, отзывы о работодателях, обсуждение тестовых заданий, вакансии, цены на рынке труда, IT события, интересные видео и многое другое.
+
+- Подпишитесь на рассылку вакансий под себя
+
+### После прохождения испытательного срока жду твою [историю успеха](http://javaops.ru/view/story)
+
+### Основные сайты поиска работы:
+- Яндекс агрегатор
+- HH
+- LinkedIn
+- djinni.co (более актуально для Украины)
+
+## Как выжить на испытательном сроке
+- Учись грамотно формулировать проблему. Проблема "у меня не работает" может иметь тысячи причин. В
+ процессе формулирования очень часто приходит ее решение.
+- Учись инвестигировать проблему. Внимательное чтение логов и умение дебажить - основные навыки
+ разработчика. В логах надо читать верх самого нижнего эксепшена - там причина всей портянки.
+- Грамотно уделяй время каждой проблеме. Две крайности - сразу бросаться за помощью и
+ бится нам ней часами.
+ Пробуй решить ее сам и в зависимости от проблемы выделяй на это разумное время.
+- Если тебе что-то объясняют по проекту - обязательно записывай.
+- Когда получаешь задачу - уточни все очень подробно.
+- Получай в процессе решения обратную связь - в том ли направлении ты идешь.
+- Не игнорируй совместные ланчи (курилки)
+- Готовься к стендапам/летучкам. Задавай на них вменяемые вопросы. Выказывай заинтересованность
+- Выдели самое главное путем опроса босса и важных коллег. Не распыляйся на мелочи.
+- [**Советы новичкам**](http://blog.csssr.ru/2016/09/19/how-to-be-a-beginner-developer)
+
+## [Отзывы по стажировке Topjava](https://vk.com/topic-74381644_30447246)
diff --git a/description.md b/description.md
new file mode 100644
index 000000000000..d01afc2e22a7
--- /dev/null
+++ b/description.md
@@ -0,0 +1,76 @@
+#### Разработка полнофункционального Spring/JPA Enterprise приложения c авторизацией и правами доступа на основе ролей с использованием наиболее популярных инструментов и технологий Java: Maven, Spring MVC, Security, JPA(Hibernate), REST(Jackson), Bootstrap (css,js), datatables, jQuery + plugins, Java 8 Stream and Time API и сохранением в базах данных Postgresql и HSQLDB.
+
+- Основное внимание будет уделяться способам решения многочисленных проблем разработки в Spring/JPA, а также структурному (красивому и надежному) java кодированию и архитектуре приложения.
+- Каждая итерация проекта закрепляется домашним заданием по реализации схожей функциональности. Следующее занятие начинается с разбора домашних заданий.
+- Большое внимание уделяется тестированию кода: в проекте более 100 JUnit тестов.
+- Несмотря на относительно небольшой размер, приложение разрабатывается с нуля как большой проект (например мы используем кэш 2-го уровня Hibernate, настраиваем Jackson для работы с ленивой загрузкой
+Hibernate, делаем конверторы для типов LocalDateTime (Java 8 time API), которые еще не поддерживаются ни JPA/Hibernate, ни Jackson/json).
+ Разбираются архитектурные паттерны: слои приложения и как правильно разбивать логику по слоям, когда нужно применять Data Transfer Object.
+ Т.е на выходе получается не учебный проект, а хорошо маштабируемый шаблон для большого проекта на всех пройденных технологиях.
+- Большое внимание уделяется деталям: популяция базы, использование транзакционности, тесты сервисов и REST
+ контроллеров, насторойка EntityManagerFactory,
+ выбор реализации пула коннектов. Особое внимание уделяется работе с базой: через Spring JDBC, Spring ORM и
+ Spring Data Jpa.
+- Используются самые востребованные на сегодняшний момент фреймворки: Maven, Spring Security 4
+ вместе с Spring Security Test, наиболее удобный для работы с базой проект Spring Data Jpa, библиотека логирования logback, реализующая SLF4J, повсеместно используемый Bootstrap и jQuery.
+
+#### Демо разрабатываемого приложения
+
+## План проекта (ссылки на некоторые темы открыты для просмотра)
+### Архитектура проекта. Персистентность.
+- Системы управления версиями
+- Java 8: Lambda, Stream API
+- Обзор используемых в проекте технологий и инструментов.
+- Инструмент сборки Maven.
+- WAR. Веб-контейнер Tomcat. Сервлеты.
+- Логирование.
+- Обзор стандартных библиотек. Apache Commons, Guava
+- Слои приложения. Создание каркаса приложения.
+- Обзор Spring Framework. Spring Context.
+- Тестирование через JUnit.
+- Spring Test
+- Базы данных. PostgreSQL. Обзор NoSQL и Java persistence solution без ORM.
+- Настройка Database в IDEA.
+- Скрипты инициализации базы. Spring Jdbc Template.
+- Spring: инициализация и популирование DB
+- ORM. Hibernate. JPA.
+- Поддержка HSQLDB
+- Транзакции
+- Профили Maven и Spring
+- Пул коннектов
+- Spring Data JPA
+- Кэш Hibernate
+
+### Разработка WEB
+- Spring кэш
+- Spring Web
+- JSP, JSTL, i18n
+- Tomcat maven plugin. JNDI
+- Spring Web MVC
+- Spring Internationalization
+- Тестирование Spring MVC
+- REST контроллеры
+- Тестирование REST контроллеров. Jackson.
+- jackson-datatype-hibernate. Тестирование через матчеры.
+- Тестирование через SoapUi. UTF-8
+- WebJars.
+- Bootstrap. jQuery datatables.
+- AJAX. jQuery. Notifications.
+- Spring Security
+- Spring Binding/Validation
+- Работа с datatables через Ajax.
+- Spring Security Test
+- [Кастомизация JSON (@JsonView) и валидации (groups)](https://drive.google.com/open?id=0B9Ye2auQ_NsFRTFsTjVHR2dXczA)
+- Encoding password
+- CSRF (добавление в проект защиты от межсайтовой подделки запроса)
+- form-login. Spring Security Taglib
+- Handler interceptor
+- Spring Exception Handling
+- Смена локали
+- Фильтрация JSON через @JsonView
+- Защита от XSS (Cross Site Scripting)
+- Деплой в Heroku
+- Локализация datatables, ошибок валидации
+- Обработка ошибок 404 (NotFound)
+- Доступ к AuthorizedUser
+- Собеседование. Разработка ПО
diff --git a/pom.xml b/pom.xml
index c8a1c78f3b29..e3b8143e3e63 100644
--- a/pom.xml
+++ b/pom.xml
@@ -24,7 +24,7 @@
org.apache.maven.pluginsmaven-compiler-plugin
- 3.1
+ 3.7.0${java.version}${java.version}
diff --git a/src/main/Patches/hv0/Prepare_to_HW0.patch b/src/main/Patches/hv0/Prepare_to_HW0.patch
new file mode 100644
index 000000000000..de0e3a4091f7
--- /dev/null
+++ b/src/main/Patches/hv0/Prepare_to_HW0.patch
@@ -0,0 +1,137 @@
+Index: src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+--- src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java (revision )
++++ src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java (revision )
+@@ -0,0 +1,35 @@
++package ru.javawebinar.topjava.util;
++
++import ru.javawebinar.topjava.model.UserMeal;
++import ru.javawebinar.topjava.model.UserMealWithExceed;
++
++import java.time.LocalDateTime;
++import java.time.LocalTime;
++import java.time.Month;
++import java.util.Arrays;
++import java.util.List;
++
++/**
++ * GKislin
++ * 31.05.2015.
++ */
++public class UserMealsUtil {
++ public static void main(String[] args) {
++ List mealList = Arrays.asList(
++ new UserMeal(LocalDateTime.of(2015, Month.MAY, 30,10,0), "Завтрак", 500),
++ new UserMeal(LocalDateTime.of(2015, Month.MAY, 30,13,0), "Обед", 1000),
++ new UserMeal(LocalDateTime.of(2015, Month.MAY, 30,20,0), "Ужин", 500),
++ new UserMeal(LocalDateTime.of(2015, Month.MAY, 31,10,0), "Завтрак", 1000),
++ new UserMeal(LocalDateTime.of(2015, Month.MAY, 31,13,0), "Обед", 500),
++ new UserMeal(LocalDateTime.of(2015, Month.MAY, 31,20,0), "Ужин", 510)
++ );
++ getFilteredWithExceeded(mealList, LocalTime.of(7, 0), LocalTime.of(12,0), 2000);
++// .toLocalDate();
++// .toLocalTime();
++ }
++
++ public static List getFilteredWithExceeded(List mealList, LocalTime startTime, LocalTime endTime, int caloriesPerDay) {
++ // TODO return filtered list with correctly exceeded field
++ return null;
++ }
++}
+Index: src/main/java/ru/javawebinar/topjava/util/TimeUtil.java
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+--- src/main/java/ru/javawebinar/topjava/util/TimeUtil.java (revision )
++++ src/main/java/ru/javawebinar/topjava/util/TimeUtil.java (revision )
+@@ -0,0 +1,13 @@
++package ru.javawebinar.topjava.util;
++
++import java.time.LocalTime;
++
++/**
++ * GKislin
++ * 07.01.2015.
++ */
++public class TimeUtil {
++ public static boolean isBetween(LocalTime lt, LocalTime startTime, LocalTime endTime) {
++ return lt.compareTo(startTime) >= 0 && lt.compareTo(endTime) <= 0;
++ }
++}
+Index: src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+--- src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java (revision )
++++ src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java (revision )
+@@ -0,0 +1,24 @@
++package ru.javawebinar.topjava.model;
++
++import java.time.LocalDateTime;
++
++/**
++ * GKislin
++ * 11.01.2015.
++ */
++public class UserMealWithExceed {
++ private final LocalDateTime dateTime;
++
++ private final String description;
++
++ private final int calories;
++
++ private final boolean exceed;
++
++ public UserMealWithExceed(LocalDateTime dateTime, String description, int calories, boolean exceed) {
++ this.dateTime = dateTime;
++ this.description = description;
++ this.calories = calories;
++ this.exceed = exceed;
++ }
++}
+Index: src/main/java/ru/javawebinar/topjava/model/UserMeal.java
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+--- src/main/java/ru/javawebinar/topjava/model/UserMeal.java (revision )
++++ src/main/java/ru/javawebinar/topjava/model/UserMeal.java (revision )
+@@ -0,0 +1,33 @@
++package ru.javawebinar.topjava.model;
++
++import java.time.LocalDateTime;
++
++/**
++ * GKislin
++ * 11.01.2015.
++ */
++public class UserMeal {
++ private final LocalDateTime dateTime;
++
++ private final String description;
++
++ private final int calories;
++
++ public UserMeal(LocalDateTime dateTime, String description, int calories) {
++ this.dateTime = dateTime;
++ this.description = description;
++ this.calories = calories;
++ }
++
++ public LocalDateTime getDateTime() {
++ return dateTime;
++ }
++
++ public String getDescription() {
++ return description;
++ }
++
++ public int getCalories() {
++ return calories;
++ }
++}
diff --git a/src/main/Patches/hv1/1_0_fix.patch b/src/main/Patches/hv1/1_0_fix.patch
new file mode 100644
index 000000000000..d4b8257bc45e
--- /dev/null
+++ b/src/main/Patches/hv1/1_0_fix.patch
@@ -0,0 +1,183 @@
+Index: src/main/java/ru/javawebinar/topjava/Main.java
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+--- src/main/java/ru/javawebinar/topjava/Main.java (revision d1f6a45bc89fb192025b1627657554edd55fa205)
++++ src/main/java/ru/javawebinar/topjava/Main.java (revision )
+@@ -1,11 +1,8 @@
+ package ru.javawebinar.topjava;
+
+ /**
+- * User: gkislin
+- * Date: 05.08.2015
+- *
+- * @link http://caloriesmng.herokuapp.com/
+- * @link https://github.com/JavaOPs/topjava
++ * @see Demo
++ * @see Initial project
+ */
+ public class Main {
+ public static void main(String[] args) {
+Index: src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java
+===================================================================
+--- src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java (revision d1f6a45bc89fb192025b1627657554edd55fa205)
++++ src/main/java/ru/javawebinar/topjava/model/MealWithExceed.java (revision )
+@@ -2,11 +2,7 @@
+
+ import java.time.LocalDateTime;
+
+-/**
+- * GKislin
+- * 11.01.2015.
+- */
+-public class UserMealWithExceed {
++public class MealWithExceed {
+ private final LocalDateTime dateTime;
+
+ private final String description;
+@@ -15,7 +11,7 @@
+
+ private final boolean exceed;
+
+- public UserMealWithExceed(LocalDateTime dateTime, String description, int calories, boolean exceed) {
++ public MealWithExceed(LocalDateTime dateTime, String description, int calories, boolean exceed) {
+ this.dateTime = dateTime;
+ this.description = description;
+ this.calories = calories;
+Index: src/main/java/ru/javawebinar/topjava/model/UserMeal.java
+===================================================================
+--- src/main/java/ru/javawebinar/topjava/model/UserMeal.java (revision d1f6a45bc89fb192025b1627657554edd55fa205)
++++ src/main/java/ru/javawebinar/topjava/model/Meal.java (revision )
+@@ -2,18 +2,14 @@
+
+ import java.time.LocalDateTime;
+
+-/**
+- * GKislin
+- * 11.01.2015.
+- */
+-public class UserMeal {
++public class Meal {
+ private final LocalDateTime dateTime;
+
+ private final String description;
+
+ private final int calories;
+
+- public UserMeal(LocalDateTime dateTime, String description, int calories) {
++ public Meal(LocalDateTime dateTime, String description, int calories) {
+ this.dateTime = dateTime;
+ this.description = description;
+ this.calories = calories;
+Index: .gitignore
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+--- .gitignore (revision d1f6a45bc89fb192025b1627657554edd55fa205)
++++ .gitignore (revision )
+@@ -3,6 +3,4 @@
+ target
+ *.iml
+ log
+-
+-
+-
++*.patch
+\ No newline at end of file
+Index: src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java
+===================================================================
+--- src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java (revision d1f6a45bc89fb192025b1627657554edd55fa205)
++++ src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java (revision d1f6a45bc89fb192025b1627657554edd55fa205)
+@@ -1,35 +0,0 @@
+-package ru.javawebinar.topjava.util;
+-
+-import ru.javawebinar.topjava.model.UserMeal;
+-import ru.javawebinar.topjava.model.UserMealWithExceed;
+-
+-import java.time.LocalDateTime;
+-import java.time.LocalTime;
+-import java.time.Month;
+-import java.util.Arrays;
+-import java.util.List;
+-
+-/**
+- * GKislin
+- * 31.05.2015.
+- */
+-public class UserMealsUtil {
+- public static void main(String[] args) {
+- List mealList = Arrays.asList(
+- new UserMeal(LocalDateTime.of(2015, Month.MAY, 30,10,0), "Завтрак", 500),
+- new UserMeal(LocalDateTime.of(2015, Month.MAY, 30,13,0), "Обед", 1000),
+- new UserMeal(LocalDateTime.of(2015, Month.MAY, 30,20,0), "Ужин", 500),
+- new UserMeal(LocalDateTime.of(2015, Month.MAY, 31,10,0), "Завтрак", 1000),
+- new UserMeal(LocalDateTime.of(2015, Month.MAY, 31,13,0), "Обед", 500),
+- new UserMeal(LocalDateTime.of(2015, Month.MAY, 31,20,0), "Ужин", 510)
+- );
+- getFilteredWithExceeded(mealList, LocalTime.of(7, 0), LocalTime.of(12,0), 2000);
+-// .toLocalDate();
+-// .toLocalTime();
+- }
+-
+- public static List getFilteredWithExceeded(List mealList, LocalTime startTime, LocalTime endTime, int caloriesPerDay) {
+- // TODO return filtered list with correctly exceeded field
+- return null;
+- }
+-}
+Index: pom.xml
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+--- pom.xml (revision d1f6a45bc89fb192025b1627657554edd55fa205)
++++ pom.xml (revision )
+@@ -24,7 +24,7 @@
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+- 3.1
++ 3.7.0
+
+ ${java.version}
+ ${java.version}
+Index: src/main/java/ru/javawebinar/topjava/util/MealsUtil.java
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+--- src/main/java/ru/javawebinar/topjava/util/MealsUtil.java (revision )
++++ src/main/java/ru/javawebinar/topjava/util/MealsUtil.java (revision )
+@@ -0,0 +1,31 @@
++package ru.javawebinar.topjava.util;
++
++import ru.javawebinar.topjava.model.Meal;
++import ru.javawebinar.topjava.model.MealWithExceed;
++
++import java.time.LocalDateTime;
++import java.time.LocalTime;
++import java.time.Month;
++import java.util.Arrays;
++import java.util.List;
++
++public class MealsUtil {
++ public static void main(String[] args) {
++ List mealList = Arrays.asList(
++ new Meal(LocalDateTime.of(2015, Month.MAY, 30,10,0), "Завтрак", 500),
++ new Meal(LocalDateTime.of(2015, Month.MAY, 30,13,0), "Обед", 1000),
++ new Meal(LocalDateTime.of(2015, Month.MAY, 30,20,0), "Ужин", 500),
++ new Meal(LocalDateTime.of(2015, Month.MAY, 31,10,0), "Завтрак", 1000),
++ new Meal(LocalDateTime.of(2015, Month.MAY, 31,13,0), "Обед", 500),
++ new Meal(LocalDateTime.of(2015, Month.MAY, 31,20,0), "Ужин", 510)
++ );
++ getFilteredWithExceeded(mealList, LocalTime.of(7, 0), LocalTime.of(12,0), 2000);
++// .toLocalDate();
++// .toLocalTime();
++ }
++
++ public static List getFilteredWithExceeded(List mealList, LocalTime startTime, LocalTime endTime, int caloriesPerDay) {
++ // TODO return filtered list with correctly exceeded field
++ return null;
++ }
++}
diff --git a/src/main/Patches/hv1/1_1_HW0_stream.patch b/src/main/Patches/hv1/1_1_HW0_stream.patch
new file mode 100644
index 000000000000..2f9f4effa454
--- /dev/null
+++ b/src/main/Patches/hv1/1_1_HW0_stream.patch
@@ -0,0 +1,117 @@
+Index: src/main/java/ru/javawebinar/topjava/model/Meal.java
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+--- src/main/java/ru/javawebinar/topjava/model/Meal.java (date 1499897563000)
++++ src/main/java/ru/javawebinar/topjava/model/Meal.java (revision )
+@@ -1,6 +1,8 @@
+ package ru.javawebinar.topjava.model;
+
++import java.time.LocalDate;
+ import java.time.LocalDateTime;
++import java.time.LocalTime;
+
+ public class Meal {
+ private final LocalDateTime dateTime;
+@@ -26,4 +28,12 @@
+ public int getCalories() {
+ return calories;
+ }
++
++ public LocalDate getDate() {
++ return dateTime.toLocalDate();
++ }
++
++ public LocalTime getTime() {
++ return dateTime.toLocalTime();
++ }
+ }
+Index: src/main/java/ru/javawebinar/topjava/util/MealsUtil.java
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+--- src/main/java/ru/javawebinar/topjava/util/MealsUtil.java (date 1499897563000)
++++ src/main/java/ru/javawebinar/topjava/util/MealsUtil.java (revision )
+@@ -3,29 +3,41 @@
+ import ru.javawebinar.topjava.model.Meal;
+ import ru.javawebinar.topjava.model.MealWithExceed;
+
++import java.time.LocalDate;
+ import java.time.LocalDateTime;
+ import java.time.LocalTime;
+ import java.time.Month;
+ import java.util.Arrays;
+ import java.util.List;
++import java.util.Map;
++import java.util.stream.Collectors;
+
+ public class MealsUtil {
+ public static void main(String[] args) {
+- List mealList = Arrays.asList(
+- new Meal(LocalDateTime.of(2015, Month.MAY, 30,10,0), "Завтрак", 500),
+- new Meal(LocalDateTime.of(2015, Month.MAY, 30,13,0), "Обед", 1000),
+- new Meal(LocalDateTime.of(2015, Month.MAY, 30,20,0), "Ужин", 500),
+- new Meal(LocalDateTime.of(2015, Month.MAY, 31,10,0), "Завтрак", 1000),
+- new Meal(LocalDateTime.of(2015, Month.MAY, 31,13,0), "Обед", 500),
+- new Meal(LocalDateTime.of(2015, Month.MAY, 31,20,0), "Ужин", 510)
++ List meals = Arrays.asList(
++ new Meal(LocalDateTime.of(2015, Month.MAY, 30, 10, 0), "Завтрак", 500),
++ new Meal(LocalDateTime.of(2015, Month.MAY, 30, 13, 0), "Обед", 1000),
++ new Meal(LocalDateTime.of(2015, Month.MAY, 30, 20, 0), "Ужин", 500),
++ new Meal(LocalDateTime.of(2015, Month.MAY, 31, 10, 0), "Завтрак", 1000),
++ new Meal(LocalDateTime.of(2015, Month.MAY, 31, 13, 0), "Обед", 500),
++ new Meal(LocalDateTime.of(2015, Month.MAY, 31, 20, 0), "Ужин", 510)
+ );
+- getFilteredWithExceeded(mealList, LocalTime.of(7, 0), LocalTime.of(12,0), 2000);
+-// .toLocalDate();
+-// .toLocalTime();
++ List mealsWithExceeded = getFilteredWithExceeded(meals, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000);
++ mealsWithExceeded.forEach(System.out::println);
+ }
+
+- public static List getFilteredWithExceeded(List mealList, LocalTime startTime, LocalTime endTime, int caloriesPerDay) {
+- // TODO return filtered list with correctly exceeded field
+- return null;
++ public static List getFilteredWithExceeded(List meals, LocalTime startTime, LocalTime endTime, int caloriesPerDay) {
++ Map caloriesSumByDate = meals.stream()
++ .collect(
++ Collectors.groupingBy(Meal::getDate, Collectors.summingInt(Meal::getCalories))
++// Collectors.toMap(Meal::getDate, Meal::getCalories, Integer::sum)
++ );
++
++ return meals.stream()
++ .filter(meal -> TimeUtil.isBetween(meal.getTime(), startTime, endTime))
++ .map(meal ->
++ new MealWithExceed(meal.getDateTime(), meal.getDescription(), meal.getCalories(),
++ caloriesSumByDate.get(meal.getDate()) > caloriesPerDay))
++ .collect(Collectors.toList());
+ }
+-}
++}
+\ No newline at end of file
+Index: src/main/java/ru/javawebinar/topjava/model/MealWithExceed.java
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+--- src/main/java/ru/javawebinar/topjava/model/MealWithExceed.java (date 1499897563000)
++++ src/main/java/ru/javawebinar/topjava/model/MealWithExceed.java (revision )
+@@ -17,4 +17,14 @@
+ this.calories = calories;
+ this.exceed = exceed;
+ }
+-}
++
++ @Override
++ public String toString() {
++ return "UserMealWithExceed{" +
++ "dateTime=" + dateTime +
++ ", description='" + description + '\'' +
++ ", calories=" + calories +
++ ", exceed=" + exceed +
++ '}';
++ }
++}
+\ No newline at end of file
diff --git a/src/main/Patches/hv1/1_2_HW0_cycle.patch b/src/main/Patches/hv1/1_2_HW0_cycle.patch
new file mode 100644
index 000000000000..4ecbb830ff9e
--- /dev/null
+++ b/src/main/Patches/hv1/1_2_HW0_cycle.patch
@@ -0,0 +1,57 @@
+Index: src/main/java/ru/javawebinar/topjava/util/MealsUtil.java
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+--- src/main/java/ru/javawebinar/topjava/util/MealsUtil.java (date 1499897832000)
++++ src/main/java/ru/javawebinar/topjava/util/MealsUtil.java (revision )
+@@ -7,9 +7,7 @@
+ import java.time.LocalDateTime;
+ import java.time.LocalTime;
+ import java.time.Month;
+-import java.util.Arrays;
+-import java.util.List;
+-import java.util.Map;
++import java.util.*;
+ import java.util.stream.Collectors;
+
+ public class MealsUtil {
+@@ -24,6 +22,8 @@
+ );
+ List mealsWithExceeded = getFilteredWithExceeded(meals, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000);
+ mealsWithExceeded.forEach(System.out::println);
++
++ System.out.println(getFilteredWithExceededByCycle(meals, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000));
+ }
+
+ public static List getFilteredWithExceeded(List meals, LocalTime startTime, LocalTime endTime, int caloriesPerDay) {
+@@ -35,9 +35,25 @@
+
+ return meals.stream()
+ .filter(meal -> TimeUtil.isBetween(meal.getTime(), startTime, endTime))
+- .map(meal ->
+- new MealWithExceed(meal.getDateTime(), meal.getDescription(), meal.getCalories(),
+- caloriesSumByDate.get(meal.getDate()) > caloriesPerDay))
++ .map(meal -> createWithExceed(meal, caloriesSumByDate.get(meal.getDate()) > caloriesPerDay))
+ .collect(Collectors.toList());
+ }
++
++ public static List getFilteredWithExceededByCycle(List meals, LocalTime startTime, LocalTime endTime, int caloriesPerDay) {
++
++ final Map caloriesSumByDate = new HashMap<>();
++ meals.forEach(meal -> caloriesSumByDate.merge(meal.getDate(), meal.getCalories(), Integer::sum));
++
++ final List mealsWithExceeded = new ArrayList<>();
++ meals.forEach(meal -> {
++ if (TimeUtil.isBetween(meal.getTime(), startTime, endTime)) {
++ mealsWithExceeded.add(createWithExceed(meal, caloriesSumByDate.get(meal.getDate()) > caloriesPerDay));
++ }
++ });
++ return mealsWithExceeded;
++ }
++
++ public static MealWithExceed createWithExceed(Meal meal, boolean exceeded) {
++ return new MealWithExceed(meal.getDateTime(), meal.getDescription(), meal.getCalories(), exceeded);
++ }
+ }
+\ No newline at end of file
diff --git a/src/main/Patches/hv1/1_3_HW0_optional2.patch b/src/main/Patches/hv1/1_3_HW0_optional2.patch
new file mode 100644
index 000000000000..26dec67cb4e9
--- /dev/null
+++ b/src/main/Patches/hv1/1_3_HW0_optional2.patch
@@ -0,0 +1,90 @@
+Index: src/main/java/ru/javawebinar/topjava/util/MealsUtil.java
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+--- src/main/java/ru/javawebinar/topjava/util/MealsUtil.java (date 1509555460000)
++++ src/main/java/ru/javawebinar/topjava/util/MealsUtil.java (revision )
+@@ -8,7 +8,12 @@
+ import java.time.LocalTime;
+ import java.time.Month;
+ import java.util.*;
++import java.util.stream.Collector;
+ import java.util.stream.Collectors;
++import java.util.stream.Stream;
++
++import static java.util.function.Function.identity;
++import static java.util.stream.Collectors.toList;
+
+ public class MealsUtil {
+ public static void main(String[] args) {
+@@ -24,6 +29,8 @@
+ mealsWithExceeded.forEach(System.out::println);
+
+ System.out.println(getFilteredWithExceededByCycle(meals, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000));
++ System.out.println(getFilteredWithExceededInOnePass(meals, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000));
++ System.out.println(getFilteredWithExceededInOnePass2(meals, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000));
+ }
+
+ public static List getFilteredWithExceeded(List meals, LocalTime startTime, LocalTime endTime, int caloriesPerDay) {
+@@ -36,7 +43,7 @@
+ return meals.stream()
+ .filter(meal -> TimeUtil.isBetween(meal.getTime(), startTime, endTime))
+ .map(meal -> createWithExceed(meal, caloriesSumByDate.get(meal.getDate()) > caloriesPerDay))
+- .collect(Collectors.toList());
++ .collect(toList());
+ }
+
+ public static List getFilteredWithExceededByCycle(List meals, LocalTime startTime, LocalTime endTime, int caloriesPerDay) {
+@@ -53,6 +60,51 @@
+ return mealsWithExceeded;
+ }
+
++ public static List getFilteredWithExceededInOnePass(List meals, LocalTime startTime, LocalTime endTime, int caloriesPerDay) {
++ Collection> list = meals.stream()
++ .collect(Collectors.groupingBy(Meal::getDate)).values();
++
++ return list.stream().flatMap(dayMeals -> {
++ boolean exceed = dayMeals.stream().mapToInt(Meal::getCalories).sum() > caloriesPerDay;
++ return dayMeals.stream().filter(meal ->
++ TimeUtil.isBetween(meal.getTime(), startTime, endTime))
++ .map(meal -> createWithExceed(meal, exceed));
++ }).collect(toList());
++ }
++
++ public static List getFilteredWithExceededInOnePass2(List meals, LocalTime startTime, LocalTime endTime, int caloriesPerDay) {
++ final class Aggregate {
++ private final List dailyMeals = new ArrayList<>();
++ private int dailySumOfCalories;
++
++ private void accumulate(Meal meal) {
++ dailySumOfCalories += meal.getCalories();
++ if (TimeUtil.isBetween(meal.getDateTime().toLocalTime(), startTime, endTime)) {
++ dailyMeals.add(meal);
++ }
++ }
++
++ // never invoked if the upstream is sequential
++ private Aggregate combine(Aggregate that) {
++ this.dailySumOfCalories += that.dailySumOfCalories;
++ this.dailyMeals.addAll(that.dailyMeals);
++ return this;
++ }
++
++ private Stream finisher() {
++ final boolean exceed = dailySumOfCalories > caloriesPerDay;
++ return dailyMeals.stream().map(meal -> createWithExceed(meal, exceed));
++ }
++ }
++
++ Collection> values = meals.stream()
++ .collect(Collectors.groupingBy(Meal::getDate,
++ Collector.of(Aggregate::new, Aggregate::accumulate, Aggregate::combine, Aggregate::finisher))
++ ).values();
++
++ return values.stream().flatMap(identity()).collect(toList());
++ }
++
+ public static MealWithExceed createWithExceed(Meal meal, boolean exceeded) {
+ return new MealWithExceed(meal.getDateTime(), meal.getDescription(), meal.getCalories(), exceeded);
+ }
diff --git a/src/main/Patches/hv1/1_4_switch_to_war.patch b/src/main/Patches/hv1/1_4_switch_to_war.patch
new file mode 100644
index 000000000000..ed7403bcf79b
--- /dev/null
+++ b/src/main/Patches/hv1/1_4_switch_to_war.patch
@@ -0,0 +1,83 @@
+Index: src/main/webapp/users.jsp
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+--- src/main/webapp/users.jsp (revision )
++++ src/main/webapp/users.jsp (revision )
+@@ -0,0 +1,10 @@
++<%@ page contentType="text/html;charset=UTF-8" language="java" %>
++
++
++ Users
++
++
++