<repo_name>artsiom-tsaryonau/pmc<file_sep>/build.gradle
apply plugin: 'eclipse'
apply plugin: 'java'

allprojects {
	group = 'com.epam.app.pmc'
}

subprojects {
	apply plugin: 'java'
	apply plugin: 'eclipse'
    repositories {
        mavenCentral()
    }
    dependencies {
        testCompile 'junit:junit:4.11'
    }
}

buildscript {
    repositories {
        mavenCentral()
        jcenter()
    }

    dependencies {
        classpath 'net.saliman:gradle-liquibase-plugin:1.0.0'
        classpath 'net.saliman:groovy-liquibase-dsl:1.0.0'
        classpath 'org.postgresql:postgresql:9.3-1102-jdbc41'
        classpath 'org.gradle.api.plugins:gradle-tomcat-plugin:0.9.9'
    }
}
<file_sep>/pmc-web/src/main/resources/oauth_consumer.properties
graph.facebook.com.consumer_key = 774300602605348
graph.facebook.com.consumer_secret = 1001fe29d51104ea7b1a657a83278c9d<file_sep>/pmc-db/build.gradle
apply plugin: 'liquibase'

liquibase {
    activities {
        main {
            changeLogFile 'src/main/liquibase/com/epam/app/pmc/db/changelog-1.groovy'
            url 'jdbc:postgresql://localhost:5432/pmc'
            username 'postgres'
            password '<PASSWORD>'
        }
    }

    runList = 'main'
}<file_sep>/README.md
pmc
===

project management system
<file_sep>/pmc-web/src/main/java/com/epam/app/pmc/vaadin/component/usercomponent/experimental/elements/table/UserTaskTable.java
package com.epam.app.pmc.vaadin.component.usercomponent.experimental.elements.table;

import com.epam.app.pmc.vaadin.component.table.ITable;
import com.epam.app.pmc.vaadin.component.util.StringValues;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.ui.Table;

import java.util.List;


public class UserTaskTable extends Table implements ITable<Object> {

    @Override
    public void attach() {
        setVisibleColumns(StringValues.USER_TASKS_TABLE);
        setSelectable(true);
        setImmediate(true);

        super.attach();
    }

    @Override
    public <T> IndexedContainer loadData(List<T> data) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public <T> IndexedContainer loadFilteredData(List<T> data) {
        // TODO Auto-generated method stub
        return null;
    }

}
<file_sep>/pmc-repository/src/main/java/com/epam/app/pmc/repository/api/AssignedDeveloperExtendedRepository.java
package com.epam.app.pmc.repository.api;

import com.epam.app.pmc.model.AssignedDeveloper;
import com.epam.app.pmc.model.AssignedDeveloperExtended;

import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Bring additional methods to Assigned developer repository.
 *
 *
 * @author Artsiom_Tsaryonau
 */
@Repository("assignedDeveloperExtendedRepository")
public class AssignedDeveloperExtendedRepository {

    protected static final String GET_DEVELOPERS_BY_PROJECT_ID = "AssignedDeveloper.getDevelopersByProjectId";
    protected static final String GET_PROJECT_BY_DEVELOPER_ID = "AssignedDeveloper.getProjectByDeveloperId";
    protected static final String GET_DEVELOPERS_BY_PROJECT_JOIN_INFORMATION = "AssignedDeveloper.getDevelopersByProjectJoinInformation";
    protected static final String GET_ASSIGNED_DEVELOPER_BY_PROJECT_AND_DEVELOPER_ID = "AssignedDeveloper.getDeveloperByTwoIds";
    protected static final String RESIGN_DEVELOPER_FROM_PROJECT = "AssignedDeveloper.resignDeveloper";

    @Autowired
    protected SqlSessionTemplate sqlSessionTemplate;

    public List<AssignedDeveloper> getDevelopersByProject(String projectId) {
        return sqlSessionTemplate.selectList(GET_DEVELOPERS_BY_PROJECT_ID, projectId);
    }

    public List<AssignedDeveloper> getProjectByDeveloper(String developerId) {
        return sqlSessionTemplate.selectList(GET_PROJECT_BY_DEVELOPER_ID, developerId);
    }

    public List<AssignedDeveloperExtended> getDeveloperForProject(String projectId) {
        return sqlSessionTemplate.selectList(GET_DEVELOPERS_BY_PROJECT_JOIN_INFORMATION, projectId);
    }

    public AssignedDeveloper getAssignedDeveloper(String developerId, String projectId) {
        Map<String, String> map = new HashMap<>();
        map.put("developerId", developerId);
        map.put("projectId", projectId);

        return sqlSessionTemplate.selectOne(GET_ASSIGNED_DEVELOPER_BY_PROJECT_AND_DEVELOPER_ID, map);
    }

    public int resignDeveloperFromProject(String developerId, String projectId) {
        Map<String, String> map = new HashMap<>();
        map.put("developerId", developerId);
        map.put("projectId", projectId);

        return sqlSessionTemplate.delete(RESIGN_DEVELOPER_FROM_PROJECT, map);
    }

}
<file_sep>/pmc-repository/src/main/java/com/epam/app/pmc/repository/api/IRepository.java
package com.epam.app.pmc.repository.api;

import java.util.List;

/**
 * Interface for operating with different database objects.
 *
 * Date: Nov 5, 2014
 *
 * @param <T> object type to operate with
 *
 * @author Artsiom_Tsaryonau
 */
public interface IRepository<T> {

    /**
     * Stores object into data.
     *
     * @param object object to store
     */
    void store(T object);

    /**
     * Returns object with certain id.
     *
     * @param id object's id
     * @return object with id
     */
    T get(String id);

    /**
     * Returns all objects in database.
     *
     * @return list of objects
     */
    List<T> getAllItems();

}
<file_sep>/pmc-web/src/main/java/com/epam/app/pmc/vaadin/component/util/StringValues.java
package com.epam.app.pmc.vaadin.component.util;


public final class StringValues {

    public static final String ALL_PROJECTS_TABLE_CAPTION = "Projects";

    public static final String[] ALL_PROJECTS_HEADERS = { "ID", "Project Name", "Project Owner" };

    public static final String ALL_DEVELOPERS_TABLE_CAPTION = "Developers";

    public static final String[] ALL_DEVELOPERS_HEADERS = { "ID", "Private information" };

    public static final String ALL_TASKS_TABLE_CAPTION = "Tasks";

    public static final String[] ALL_TASKS_TABLE_HEADERS = { "ID", "Description", "Developer", "Project", "Status", "Weight" };

    public static final String[] ALL_MAIN_PAGE_TABS = { "Projects", "Developers", "Tasks" };

    public static final String NEW_PROJECT_MODAL_WINDOW_CAPTION = "New Project";

    public static final String PROJECT_DETAILS_WINDOW_CAPTION = "Project Details";

    public static final String DEVELOPER_DETATILS_WINDOW_CAPTION = "Developer Details";

    public static final String NEW_DEVELOPER_MODAL_WINDOW_CAPTION = "New Developer";

    public static final String NEW_TASK_MODAL_WINDOW_CAPTION = "New Task";

    public static final String TASK_DETAILS_WINDOW_CAPTION = "Task Details";

    public static final String ALL_DEVELOPERS_FOR_PROJECT_TABLE_CAPTION = "Developers";

    public static final String[] ALL_DEVELOPERS_FOR_PROJECT_HEADERS = { "ID", "Project ID", "Private information" };

    public static final String ASSIGN_TASK_WINDOW_CAPTION = "Assign task";

    public static final String[] PROJECT_TASK_HEADERS = { "ID", "Description", "Status", "Weight", "Developer" };

    public static final String[] PROJECT_DEVELOPER_HEADERS = { "ID", "Private information" };

    public static final String ASSIGN_DEVELOPER_WINDOW_CAPTION = "Assign developer";

    public static final String[] PROCEDURAL_TAB_HEADERS = { "Details", "Search" };

    public static final String LOGIN_FORM_CAPTION = "Authentication";

    public static final String[] USER_TASKS_TABLE = { "ID", "Description", "Begin date", "End date", "Status" };

}
<file_sep>/pmc-web/src/main/java/com/epam/app/pmc/vaadin/component/experimental/event/LoginFacebookEvent.java
package com.epam.app.pmc.vaadin.component.experimental.event;


public class LoginFacebookEvent {

}
<file_sep>/pmc-web/src/main/java/com/epam/app/pmc/vaadin/component/experimental/view/MainView.java
package com.epam.app.pmc.vaadin.component.experimental.view;

import com.epam.app.pmc.vaadin.component.tab.MainTab;
import com.google.common.eventbus.EventBus;
import com.vaadin.navigator.Navigator;
import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent;
import com.vaadin.ui.VerticalLayout;

public class MainView extends VerticalLayout implements IView {

    private EventBus eventBus; //eventBus.post(new LogoutEvent())

    @Override
    public void setEventBus(EventBus eventBus) {
        this.eventBus = eventBus;
        addComponent(new MainTab()); //BAD SOLUTION
    }

    @Override
    public void enter(ViewChangeEvent event) {
    }

    @Override
    public void setNavigator(Navigator navigator) {
        throw new UnsupportedOperationException("Not implemented");
    }

}
<file_sep>/pmc-service/src/main/java/com/epam/app/pmc/service/project/ProjectService.java
package com.epam.app.pmc.service.project;

import com.epam.app.pmc.model.Project;
import com.epam.app.pmc.repository.ProjectRepository;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * Service to operate with projects.
 *
 * Date: Nov 20, 2014
 *
 * @author Artsiom_Tsaryonau
 */
@Service("projectService")
public class ProjectService {

    @Autowired
    private ProjectRepository projectRepository;

    public void insertProject(Project project) {
        projectRepository.store(project);
    }

    public List<Project> findAllProjects() {
        return projectRepository.getAllItems();
    }

    public Project getProject(String id) {
        return projectRepository.get(id);
    }

    public Project getProjectByName(String name) {
        return projectRepository.getProjectByName(name);
    }

    public List<Project> filterProrjects(String projectId, String projectName, String projectOwner) {
        return projectRepository.getFilteredProjects(projectId, projectName, projectOwner);
    }
}
<file_sep>/pmc-web/src/main/java/com/epam/app/pmc/vaadin/component/modal/NewDeveloperModalWindow.java
package com.epam.app.pmc.vaadin.component.modal;

import com.epam.app.pmc.model.Developer;
import com.epam.app.pmc.vaadin.component.experimental.NavigatorUi;
import com.epam.app.pmc.vaadin.component.tab.AllDevelopersTabContent;
import com.epam.app.pmc.vaadin.component.util.DomainUtils;
import com.epam.app.pmc.vaadin.component.util.Generator;
import com.epam.app.pmc.vaadin.component.util.StringValues;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.FormLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.TextArea;
import com.vaadin.ui.Window;

public class NewDeveloperModalWindow extends Window {

    private TextArea privateInformation;
    private Button createDeveloper;
    private Button cancel;

    private HorizontalLayout buttonLayout;
    private AllDevelopersTabContent parentTab;

    public void setParentTab(AllDevelopersTabContent parentTab) {
        this.parentTab = parentTab;
    }

    @Override
    public void attach() {
        setCaption(StringValues.NEW_DEVELOPER_MODAL_WINDOW_CAPTION);
        setSizeUndefined();
        setResizable(false);
        setModal(true);

        setContent(createLayout());

        super.attach();
    }

    private FormLayout createLayout() {
        FormLayout mainLayout = null;
        privateInformation = new TextArea("Private Information");

        final NavigatorUi ui = (NavigatorUi) NavigatorUi.getCurrent();
        createDeveloper = new Button("Create");
        createDeveloper.addClickListener(new Button.ClickListener() {

            @Override
            public void buttonClick(ClickEvent event) {
                Developer developer = DomainUtils.createDeveloper(Generator.gen(), privateInformation.getValue());
                ui.getDeveloperService().insertDeveloper(developer);
                parentTab.updateAllDevelopersTable(developer);
                NewDeveloperModalWindow.this.close();
            }

        });

        cancel = new Button("Cancel");
        cancel.addClickListener(new Button.ClickListener() {

            @Override
            public void buttonClick(ClickEvent event) {
                NewDeveloperModalWindow.this.close();
            }
        });

        addCloseListener(new CloseListener(){

            @Override
            public void windowClose(CloseEvent e) {
                ui.removeWindow(NewDeveloperModalWindow.this);
            }

        });

        buttonLayout = new HorizontalLayout(createDeveloper, cancel);
        mainLayout = new FormLayout(privateInformation, buttonLayout);
        mainLayout.setMargin(true);

        return mainLayout;
    }

}
<file_sep>/pmc-web/src/main/java/com/epam/app/pmc/vaadin/component/usercomponent/experimental/elements/modal/ProjectTasksModalWindow.java
package com.epam.app.pmc.vaadin.component.usercomponent.experimental.elements.modal;

import com.vaadin.ui.Window;


public class ProjectTasksModalWindow extends Window {

}
<file_sep>/pmc-web/src/main/java/com/epam/app/pmc/vaadin/component/modal/NewTaskForProjectModalWindow.java
package com.epam.app.pmc.vaadin.component.modal;

import com.epam.app.pmc.model.Project;
import com.epam.app.pmc.model.Task;
import com.epam.app.pmc.vaadin.component.experimental.NavigatorUi;
import com.epam.app.pmc.vaadin.component.util.DomainUtils;
import com.epam.app.pmc.vaadin.component.util.Generator;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.FormLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.TextArea;
import com.vaadin.ui.TextField;


/**
 * Special extension of {@link NewTaskModalWindow}.
 *
 *
 * @author Artsiom_Tsaryonau
 */
public class NewTaskForProjectModalWindow extends NewTaskModalWindow {

    private Project project;
    private TextField projectName;

    private ProjectDetailModalWindow parentWindow;

    public void setParentModalWindow(ProjectDetailModalWindow parentWindow) {
        this.parentWindow = parentWindow;
    }

    @Override
    protected FormLayout createLayout() {
        FormLayout mainLayout = null;

        projectName = new TextField("Project Name ", project.getProjectName());
        projectName.setReadOnly(true);
        developerId = new ComboBox("Developer ID");
        description = new TextArea("Description");
        weight = new TextField("Weight");
        status = new TextField("Status");

        final NavigatorUi ui = (NavigatorUi) NavigatorUi.getCurrent();
        developerId.addItems(filterDevelopers(ui.getDeveloperService().findAllDevelopers()));

        createTask = new Button("Create");
        createTask.addClickListener(new Button.ClickListener() {

            @Override
            public void buttonClick(ClickEvent event) {
                Task task = DomainUtils.createTask(Generator.gen(), description.getValue(),
                                        developerId.getValue().toString(), status.getValue(),
                                        ui.getProjectService().getProjectByName(projectName.getValue().toString()).getProjectId(),
                                        weight.getValue());
                ui.getTaskService().insertTask(task);
                parentWindow.updateTasks(task);
                NewTaskForProjectModalWindow.this.close();
            }
        });

        cancel = new Button("Cancel");
        cancel.addClickListener(new Button.ClickListener() {

            @Override
            public void buttonClick(ClickEvent event) {
                NewTaskForProjectModalWindow.this.close();
            }
        });

        addCloseListener(new CloseListener(){

            @Override
            public void windowClose(CloseEvent e) {
                ui.removeWindow(NewTaskForProjectModalWindow.this);
            }

        });

        buttonLayout = new HorizontalLayout(createTask, cancel);
        mainLayout = new FormLayout(projectName, developerId, description, weight, status, buttonLayout);

        mainLayout.setMargin(true);
        return mainLayout;
    }

    public void setProject(Project project) {
        this.project = project;
    }
}
<file_sep>/pmc-domain/src/test/java/com/epam/app/pmc/model/TaskTest.java
package com.epam.app.pmc.model;

import static org.junit.Assert.assertEquals;

import org.junit.Before;
import org.junit.Test;

/**
 * The unit test verifies {@link Task}.
 *
 * Date: Nov 5, 2014
 *
 * @author Artsiom_Tsaryonau
 */
public class TaskTest {

    private static final String TASK_ID = "Task1234";
    private static final String DESCRIPTION = "IMPLEMENT ME";
    private static final String WEIGHT = "50";
    private static final String STATUS = "IN PROGRESS";
    private static final String TASK_PROJECT = "PROJECT_1";
    private static final String TASK_DEVELOPER = "DEVELOPER";

    private Task task;

    @Before
    public void setUp() {
        task = new Task();
        task.setTaskId(TASK_ID);
        task.setDescription(DESCRIPTION);
        task.setWeight(WEIGHT);
        task.setStatus(STATUS);
        task.setTaskProject(TASK_PROJECT);
        task.setTaskDeveloper(TASK_DEVELOPER);
    }

    @Test
    public void testPojo() {
        assertEquals(TASK_ID, task.getTaskId());
        assertEquals(DESCRIPTION, task.getDescription());
        assertEquals(WEIGHT, task.getWeight());
        assertEquals(STATUS, task.getStatus());
        assertEquals(TASK_PROJECT, task.getTaskProject());
        assertEquals(TASK_DEVELOPER, task.getTaskDeveloper());
    }
}
<file_sep>/pmc-domain/src/test/java/com/epam/app/pmc/model/DeveloperTest.java
package com.epam.app.pmc.model;

import static org.junit.Assert.assertEquals;

import org.junit.Before;
import org.junit.Test;

/**
 * The unit test verifies {@link Developer}.
 *
 * Date: Nov 5, 2014
 *
 * @author Artsiom_Tsaryonau
 */
public class DeveloperTest {

    private static final String DEVELOPER_ID = "12345";
    private static final String PRIVATE_INFORMATION = "FIO";

    private Developer developer;

    @Before
    public void setUp() {
        developer = new Developer();
        developer.setDeveloperId(DEVELOPER_ID);
        developer.setPrivateInformation(PRIVATE_INFORMATION);
    }

    @Test
    public void testPojo() {
        assertEquals(DEVELOPER_ID, developer.getDeveloperId());
        assertEquals(PRIVATE_INFORMATION, developer.getPrivateInformation());
    }

}
<file_sep>/pmc-web/src/main/java/com/epam/app/pmc/vaadin/component/usercomponent/experimental/UserPage.java
package com.epam.app.pmc.vaadin.component.usercomponent.experimental;

import com.epam.app.pmc.vaadin.component.usercomponent.experimental.elements.UserInformation;
import com.epam.app.pmc.vaadin.component.usercomponent.experimental.elements.table.UserTaskTable;
import com.vaadin.event.Action;
import com.vaadin.event.Action.Handler;
import com.vaadin.ui.HorizontalLayout;


public class UserPage extends HorizontalLayout {

    private UserInformation userInformation;
    private UserTaskTable taskTable;

    private static Action[] userTasksActions = { new Action("+Add...") };

    public UserPage() {
        userInformation = new UserInformation();
        taskTable = new UserTaskTable();
        taskTable.addActionHandler(new Handler() {

            @Override
            public Action[] getActions(Object target, Object sender) {
                return userTasksActions;
            }

            @Override
            public void handleAction(Action action, Object sender, Object target) {
                switch(action.getCaption()) {
                case "+Add...": {
                    break;
                }
                }
            }

        });
    }

    @Override
    public void attach() {
        addComponent(userInformation);
        addComponent(taskTable);

        super.attach();
    }

}
<file_sep>/pmc-web/build.gradle
apply plugin: 'war'
apply plugin: 'tomcat'

repositories {
    maven {
        url 'http://maven.vaadin.com/vaadin-addons'
    }
}

configurations {
    provided
}
sourceSets {
    main { compileClasspath += configurations.provided }
}

repositories {
    maven {
        url 'https://raw.github.com/fernandezpablo85/scribe-java/mvn-repo/'
    }
}

dependencies {
    compile project(':pmc-service')

    compile 'jstl:jstl:1.2'
    compile 'javax.servlet:jstl:1.2'

    compile 'org.springframework:spring-core:4.1.1.RELEASE'
    compile 'org.springframework:spring-context:4.1.1.RELEASE'
    compile 'org.springframework:spring-webmvc:4.1.1.RELEASE'
    compile 'org.springframework.security:spring-security-web:3.2.5.RELEASE'
    compile 'org.springframework.security:spring-security-config:3.2.5.RELEASE'
//    compile 'org.springframework.social:spring-social:1.1.0.RELEASE'
    compile 'org.springframework.social:spring-social-facebook:1.1.1.RELEASE'
    compile 'org.springframework.social:spring-social-core:1.1.0.RELEASE'
    compile 'org.springframework.social:spring-social-web:1.1.0.RELEASE'
    compile 'org.springframework.social:spring-social-config:1.1.0.RELEASE'
    compile 'org.springframework.social:spring-social-security:1.1.0.RELEASE'
    
    provided 'javax.servlet:servlet-api:2.5'

    compile 'com.vaadin:vaadin-client:7.3.5'
    compile 'com.vaadin:vaadin-server:7.3.5'
    compile 'com.vaadin:vaadin-client-compiled:7.3.5'
    compile 'com.vaadin:vaadin-themes:7.3.5'
    compile('ru.xpoft.vaadin:spring-vaadin-integration:3.1') {
        exclude group: 'org.slf4j'
    }

    compile 'com.google.guava:guava:18.0'
    compile 'org.scribe:scribe:1.3.5'
    compile ('org.brickred:socialauth-spring:2.3+') {
        exclude group: 'javax.servlet'
    }
    compile 'org.apache.httpcomponents:httpclient:4.3.6'
    compile 'org.apache.httpcomponents:httpcore:4.4'

    def tomcatVersion = '7.0.56'
    tomcat "org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}"
    tomcat "org.apache.tomcat.embed:tomcat-embed-logging-juli:${tomcatVersion}"
    tomcat("org.apache.tomcat.embed:tomcat-embed-jasper:${tomcatVersion}") {
        exclude group: 'org.eclipse.jdt.core.compiler', module: 'ecj'
    }

    runtime 'org.postgresql:postgresql:9.3-1102-jdbc41'

}
<file_sep>/pmc-web/src/main/java/com/epam/app/pmc/vaadin/component/usercomponent/experimental/elements/modal/SetTaskWindow.java
package com.epam.app.pmc.vaadin.component.usercomponent.experimental.elements.modal;

import com.vaadin.ui.Window;


public class SetTaskWindow extends Window {

}
<file_sep>/pmc-service/src/main/java/com/epam/app/pmc/service/project/AssignedDeveloperService.java
package com.epam.app.pmc.service.project;

import com.epam.app.pmc.model.AssignedDeveloper;
import com.epam.app.pmc.model.AssignedDeveloperExtended;
import com.epam.app.pmc.repository.AssignedDeveloperRepository;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * Service to operate with assigned developers.
 *
 * Date: Nov 27, 2014
 *
 * @author Artsiom_Tsaryonau
 */
@Service("assignedDeveloperService")
public class AssignedDeveloperService {

    @Autowired
    private AssignedDeveloperRepository assignedDeveloperRepository;

    public void insertAssignedDeveloper(AssignedDeveloper assignedDeveloper) {
        assignedDeveloperRepository.store(assignedDeveloper);
    }

    public List<AssignedDeveloper> findAllAssignedDevelopers() {
        return assignedDeveloperRepository.getAllItems();
    }

    public AssignedDeveloper getAssignedDeveloper(String id) {
        return assignedDeveloperRepository.get(id);
    }

    public List<AssignedDeveloper> findProjectDeveloper(String projectId) {
        return assignedDeveloperRepository.getDevelopersByProject(projectId);
    }

    public List<AssignedDeveloper> findDeveloperProjects(String developerId) {
        return assignedDeveloperRepository.getProjectByDeveloper(developerId);
    }

    public List<AssignedDeveloperExtended> findProjectDevelopersExtended(String projectId) {
        return assignedDeveloperRepository.getDeveloperForProject(projectId);
    }

    public int resignDeveloper(String projectId, String developerId) {
        return assignedDeveloperRepository.resignDeveloperFromProject(developerId, projectId);
    }

}
<file_sep>/pmc-repository/src/main/java/com/epam/app/pmc/repository/api/DeveloperExtendedRepository.java
package com.epam.app.pmc.repository.api;

import static com.epam.app.pmc.repository.util.RepositoryUtils.nullifyEmpty;
import static com.epam.app.pmc.repository.util.RepositoryUtils.wrapLikeParameters;

import com.epam.app.pmc.model.Developer;

import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Repository("developerExtendedRepository")
public class DeveloperExtendedRepository {

    protected static final String GET_NOT_ASSIGNED_TO_PROJECT = "Developer.getNotAssignedDevelopers";
    protected static final String GET_FILTERED_DEVELOPERS = "Developer.getFilteredDevelopers";

    @Autowired
    protected SqlSessionTemplate sqlSessionTemplate;

    public List<Developer> getNotAssignedDevelopers(String id) {
        return sqlSessionTemplate.selectList(GET_NOT_ASSIGNED_TO_PROJECT, id);
    }

    public List<Developer> getFilteredDevelopers(String filterId, String filterPrivateInformation) {
        Map<String, String> map = new HashMap<>();
        map.put("filterId", filterId);
        map.put("filterPrivateInformation", filterPrivateInformation);

        return sqlSessionTemplate.selectList(GET_FILTERED_DEVELOPERS, wrapLikeParameters(nullifyEmpty(map)));
    }

}
<file_sep>/pmc-web/src/main/java/com/epam/app/pmc/vaadin/component/tab/AllDevelopersTabContent.java
package com.epam.app.pmc.vaadin.component.tab;

import com.epam.app.pmc.model.Developer;
import com.epam.app.pmc.vaadin.component.experimental.NavigatorUi;
import com.epam.app.pmc.vaadin.component.functional.DevelopersSearchForm;
import com.epam.app.pmc.vaadin.component.modal.DeveloperDetailModalWindow;
import com.epam.app.pmc.vaadin.component.modal.NewDeveloperModalWindow;
import com.epam.app.pmc.vaadin.component.table.AllDevelopersTable;
import com.vaadin.data.Item;
import com.vaadin.event.Action;
import com.vaadin.event.Action.Handler;
import com.vaadin.event.ItemClickEvent;
import com.vaadin.event.ItemClickEvent.ItemClickListener;
import com.vaadin.ui.HorizontalLayout;

import java.util.List;

public class AllDevelopersTabContent extends HorizontalLayout {

    private AllDevelopersTable allDevelopersTable;
    private NewDeveloperModalWindow newDeveloperModalWindow;
    private DeveloperDetailModalWindow developerDetailModalWindow;
    private DevelopersSearchForm developersSearchForm;

    private static Action[] newAction = { new Action("+New...") };

    public AllDevelopersTabContent() {
        allDevelopersTable = new AllDevelopersTable();
        developerDetailModalWindow = new DeveloperDetailModalWindow();
        newDeveloperModalWindow = new NewDeveloperModalWindow();
        newDeveloperModalWindow.setParentTab(this);

        developersSearchForm = new DevelopersSearchForm();
        developersSearchForm.setParentTabContent(this);

        final NavigatorUi ui = (NavigatorUi) NavigatorUi.getCurrent();
        allDevelopersTable.addActionHandler(new Handler() {

            @Override
            public Action[] getActions(Object target, Object sender) {
                return newAction;
            }

            @Override
            public void handleAction(Action action, Object sender, Object target) {
                switch (action.getCaption()) {
                case "+New...": {
                    ui.addWindow(newDeveloperModalWindow);
                    break;
                }
                }
            }

        });

        allDevelopersTable.addItemClickListener(new ItemClickListener() {

            @Override
            public void itemClick(ItemClickEvent event) {
                if (event.isDoubleClick()) {
                    Object currentItemId = event.getItemId();
                    developerDetailModalWindow.setDeveloperDetailsId(allDevelopersTable
                            .getItem(currentItemId).getItemProperty("ID").getValue().toString());
                    ui.addWindow(developerDetailModalWindow);
                }
            }

        });

        allDevelopersTable.setData(ui.getDeveloperService().findAllDevelopers()); // null pointer there
    }

    public void updateAllDevelopersTable(Developer newDeveloper) {
        NavigatorUi currentUi = (NavigatorUi) NavigatorUi.getCurrent();
        List<Developer> allDevelopers = currentUi.getDeveloperService().findAllDevelopers();
        for (Developer d : allDevelopers) {
            if (newDeveloper.getDeveloperId().equals(d.getDeveloperId())) {
                Object itemId = allDevelopersTable.addItem();
                Item item = allDevelopersTable.getItem(itemId);
                item.getItemProperty("ID").setValue(d.getDeveloperId());
                item.getItemProperty("Private information").setValue(d.getPrivateInformation());
            }
        }
    }

    public void filterTableItem(String filterId, String filterPrivateInformation) {
        NavigatorUi currentUi = (NavigatorUi) NavigatorUi.getCurrent();
        allDevelopersTable.removeAllItems();
        List<Developer> list = currentUi.getDeveloperService().filterDevelopers(filterId, filterPrivateInformation);
        for(Developer d: list) {
            Object itemId = allDevelopersTable.addItem();
            Item item = allDevelopersTable.getItem(itemId);
            item.getItemProperty("ID").setValue(d.getDeveloperId());
            item.getItemProperty("Private information").setValue(d.getPrivateInformation());
        }
    }

    @Override
    public void attach() {
        addComponent(allDevelopersTable);
        addComponent(developersSearchForm);

        super.attach();
    }

}
<file_sep>/pmc-web/src/main/java/com/epam/app/pmc/vaadin/component/functional/ProjectSearchForm.java
package com.epam.app.pmc.vaadin.component.functional;

import com.epam.app.pmc.vaadin.component.functional.api.SearchForm;
import com.epam.app.pmc.vaadin.component.tab.AllProjectsTabContent;
import com.epam.app.pmc.vaadin.component.util.StringValues;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;


public class ProjectSearchForm extends SearchForm {

    private AllProjectsTabContent parentTab;

    public ProjectSearchForm() {
        labels = StringValues.ALL_PROJECTS_HEADERS;
        initComponents();

        filterTable.addClickListener(new ClickListener() {

            @Override
            public void buttonClick(ClickEvent event) {
                parentTab.filterTableItem(fields[0].getValue(), fields[1].getValue(), fields[2].getValue());
            }

        });
    }

    public void setParentTabContent(AllProjectsTabContent parentTab) {
        this.parentTab = parentTab;
    }
}
<file_sep>/pmc-domain/src/main/java/com/epam/app/pmc/model/Task.java
package com.epam.app.pmc.model;

/**
 *
 *
 * Date: Nov 5, 2014
 *
 * @author Artsiom_Tsaryonau
 */
public class Task {

    private String taskId;
    private String description;
    private String weight;
    private String status;
    private String taskProject;
    private String taskDeveloper;

    public String getTaskId() {
        return taskId;
    }

    public void setTaskId(String taskId) {
        this.taskId = taskId;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getWeight() {
        return weight;
    }

    public void setWeight(String weight) {
        this.weight = weight;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getTaskProject() {
        return taskProject;
    }

    public void setTaskProject(String taskProject) {
        this.taskProject = taskProject;
    }

    public String getTaskDeveloper() {
        return taskDeveloper;
    }

    public void setTaskDeveloper(String taskDeveloper) {
        this.taskDeveloper = taskDeveloper;
    }



}
<file_sep>/settings.gradle
rootProject.name = 'pmc'

include 'pmc-db'
include 'pmc-domain'
include 'pmc-repository'
include 'pmc-service'
include 'pmc-web'<file_sep>/pmc-repository/src/main/java/com/epam/app/pmc/repository/AssignedDeveloperRepository.java
package com.epam.app.pmc.repository;

import com.epam.app.pmc.model.AssignedDeveloper;
import com.epam.app.pmc.repository.api.AssignedDeveloperExtendedRepository;
import com.epam.app.pmc.repository.api.IRepository;

import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * Implementation of {@link IRepository} for {@link AssignedDeveloper}.
 *
 * Date: Dec 2, 2014
 *
 * @author Artsiom_Tsaryonau
 */
@Repository("assignedDeveloperRepository")
public class AssignedDeveloperRepository extends AssignedDeveloperExtendedRepository implements
        IRepository<AssignedDeveloper> {

    private static final String STORE_ASSIGNED_DEVELOPER = "AssignedDeveloper.insertAssignedDeveloper";
    private static final String GET_ASSIGNED_DEVELOPER_LIST = "AssignedDeveloper.getAssignedDeveloperList";

    @Override
    public void store(AssignedDeveloper object) {
        AssignedDeveloper exists = this.getAssignedDeveloper(object.getDeveloperId(), object.getProjectId());
        if (null != exists) {
            if (exists.getProjectId().equals(object.getProjectId()) && exists.getDeveloperId().equals(object.getDeveloperId()))
                return;
        }

        sqlSessionTemplate.insert(STORE_ASSIGNED_DEVELOPER, object);
    }

    @Override
    public AssignedDeveloper get(String id) {
        throw new UnsupportedOperationException("Cannot map ID in table with two primary IDs");
    }

    @Override
    public List<AssignedDeveloper> getAllItems() {
        return sqlSessionTemplate.selectList(GET_ASSIGNED_DEVELOPER_LIST);
    }

}
<file_sep>/pmc-web/src/main/java/com/epam/app/pmc/vaadin/component/experimental/view/UserView.java
package com.epam.app.pmc.vaadin.component.experimental.view;

import com.epam.app.pmc.vaadin.component.usercomponent.experimental.UserPage;
import com.google.common.eventbus.EventBus;
import com.vaadin.navigator.Navigator;
import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent;
import com.vaadin.ui.VerticalLayout;


public class UserView extends VerticalLayout implements IView {

    private EventBus eventBus;

    @Override
    public void setEventBus(EventBus eventBus) {
        this.eventBus = eventBus;
        addComponent(new UserPage());
    }

    @Override
    public void enter(ViewChangeEvent event) {
    }

    @Override
    public void setNavigator(Navigator navigator) {
        throw new UnsupportedOperationException("Not implemented");
    }

}
<file_sep>/pmc-service/README.md
Performs operation with application's objects<file_sep>/pmc-web/src/main/java/com/epam/app/pmc/vaadin/component/modal/NewTaskModalWindow.java
package com.epam.app.pmc.vaadin.component.modal;

import com.epam.app.pmc.model.Developer;
import com.epam.app.pmc.model.Project;
import com.epam.app.pmc.model.Task;
import com.epam.app.pmc.vaadin.component.experimental.NavigatorUi;
import com.epam.app.pmc.vaadin.component.tab.AllTasksTabContent;
import com.epam.app.pmc.vaadin.component.util.DomainUtils;
import com.epam.app.pmc.vaadin.component.util.Generator;
import com.epam.app.pmc.vaadin.component.util.StringValues;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.FormLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.TextArea;
import com.vaadin.ui.TextField;
import com.vaadin.ui.Window;

import java.util.ArrayList;
import java.util.List;

public class NewTaskModalWindow extends Window {

    private ComboBox projectName;
    protected ComboBox developerId;
    protected TextArea description;
    protected TextField weight;
    protected TextField status;
    protected Button createTask;
    protected Button cancel;

    protected HorizontalLayout buttonLayout;
    private AllTasksTabContent parentTab;

    public void setParentTab(AllTasksTabContent parentTab) {
        this.parentTab = parentTab;
    }

    @Override
    public void attach() {
        setCaption(StringValues.NEW_TASK_MODAL_WINDOW_CAPTION);
        setSizeUndefined();
        setResizable(false);
        setModal(true);

        setContent(createLayout());

        super.attach();
    }

    protected FormLayout createLayout() {
        FormLayout mainLayout = null;
        projectName = new ComboBox("Project Name");
        developerId = new ComboBox("Developer ID");
        description = new TextArea("Description");
        weight = new TextField("Weight");
        status = new TextField("Status");

        final NavigatorUi ui = (NavigatorUi) NavigatorUi.getCurrent();
        projectName.addItems(filterProjects(ui.getProjectService().findAllProjects()));
        developerId.addItems(filterDevelopers(ui.getDeveloperService().findAllDevelopers()));

        createButtonCreate(ui);
        createButtonCancel();

        addCloseListener(new CloseListener(){

            @Override
            public void windowClose(CloseEvent e) {
                ui.removeWindow(NewTaskModalWindow.this);
            }

        });

        buttonLayout = new HorizontalLayout(createTask, cancel);
        mainLayout = new FormLayout(projectName, developerId, description, weight, status, buttonLayout);

        mainLayout.setMargin(true);
        return mainLayout;
    }

    protected void createButtonCreate(final NavigatorUi ui) {
        createTask = new Button("Create");
        createTask.addClickListener(new Button.ClickListener() {

            @Override
            public void buttonClick(ClickEvent event) {
                Task task = DomainUtils.createTask(Generator.gen(), description.getValue(),
                                        developerId.getValue().toString(), status.getValue(),
                                        ui.getProjectService().getProjectByName(projectName.getValue().toString()).getProjectId(),
                                        weight.getValue());
                ui.getTaskService().insertTask(task);
                parentTab.updateAllTasksTable(task);
                NewTaskModalWindow.this.close();
            }
        });
    }

    protected void createButtonCancel() {
        cancel = new Button("Cancel");
        cancel.addClickListener(new Button.ClickListener() {

            @Override
            public void buttonClick(ClickEvent event) {
                NewTaskModalWindow.this.close();
            }
        });
    }

    private List<String> filterProjects(List<Project> list) {
        List<String> names = new ArrayList<>();
        for(Project item: list) {
            names.add(item.getProjectName());
        }

        return names;
    }

    protected List<String> filterDevelopers(List<Developer> list) {
        List<String> ids = new ArrayList<>();
        for(Developer item: list) {
            ids.add(item.getDeveloperId());
        }

        return ids;
    }

}
<file_sep>/pmc-web/src/main/java/com/epam/app/pmc/vaadin/component/usercomponent/experimental/elements/UserInformation.java
package com.epam.app.pmc.vaadin.component.usercomponent.experimental.elements;

import com.vaadin.ui.FormLayout;
import com.vaadin.ui.TextField;


public class UserInformation extends FormLayout {

    private TextField idTextField;
    private TextField privateInformationTextField;

    public UserInformation() {
        createLayout();
    }

    public void createLayout() {
        idTextField = new TextField("ID");
        privateInformationTextField = new TextField("Private information");

        addComponents(idTextField, privateInformationTextField);
    }

}
<file_sep>/pmc-web/src/main/java/com/epam/app/pmc/vaadin/component/experimental/event/LogoutEvent.java
package com.epam.app.pmc.vaadin.component.experimental.event;


public class LogoutEvent {

}
<file_sep>/pmc-repository/src/main/java/com/epam/app/pmc/repository/api/ProjectExtendedRepository.java
package com.epam.app.pmc.repository.api;

import static com.epam.app.pmc.repository.util.RepositoryUtils.nullifyEmpty;
import static com.epam.app.pmc.repository.util.RepositoryUtils.wrapLikeParameters;

import com.epam.app.pmc.model.Project;

import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Component("projectExtendedRepository")
public class ProjectExtendedRepository {

    protected static final String GET_PROJECT_BY_NAME = "Project.getProjectByName";
    protected static final String GET_FILTERED_PROJECTS = "Project.getFilteredProjects";

    @Autowired
    protected SqlSessionTemplate sqlSessionTemplate;

    public Project getProjectByName(String name) {
        return sqlSessionTemplate.selectOne(GET_PROJECT_BY_NAME, name);
    }

    public List<Project> getFilteredProjects(String projectId, String projectName, String projectOwner) {
        Map<String, String> map = new HashMap<>();
        map.put("projectId", projectId);
        map.put("projectName", projectName);
        map.put("projectOwner", projectOwner);

        return sqlSessionTemplate.selectList(GET_FILTERED_PROJECTS, wrapLikeParameters(nullifyEmpty(map)));
    }

}
<file_sep>/pmc-repository/build.gradle
dependencies {
    compile project(':pmc-domain')
    
    compile 'org.mybatis:mybatis:3.2.8'
    compile 'org.mybatis:mybatis-spring:1.2.2'
    compile 'org.springframework:spring-core:4.1.1.RELEASE'
    compile 'org.springframework:spring-context:4.1.1.RELEASE'
    compile 'org.springframework:spring-jdbc:4.1.1.RELEASE'
    compile 'org.apache.commons:commons-lang3:3.0'
}
<file_sep>/pmc-web/src/main/java/com/epam/app/pmc/vaadin/component/tab/MainTab.java
package com.epam.app.pmc.vaadin.component.tab;

import com.epam.app.pmc.vaadin.component.util.StringValues;
import com.vaadin.ui.TabSheet;

public class MainTab extends TabSheet {

    private AllProjectsTabContent allProjectsTabContent;

    private AllDevelopersTabContent allDevelopersTabContent;

    private AllTasksTabContent allTasksTabContent;

    public MainTab() {
        allProjectsTabContent = new AllProjectsTabContent();
        addTab(allProjectsTabContent, StringValues.ALL_MAIN_PAGE_TABS[0]);

        allDevelopersTabContent = new AllDevelopersTabContent();
        addTab(allDevelopersTabContent, StringValues.ALL_MAIN_PAGE_TABS[1]);

        allTasksTabContent = new AllTasksTabContent();
        addTab(allTasksTabContent, StringValues.ALL_MAIN_PAGE_TABS[2]);
    }

//    @Override
//    public void attach() {
//
//        allProjectsTabContent = new AllProjectsTabContent();
//        addTab(allProjectsTabContent, StringValues.ALL_MAIN_PAGE_TABS[0]);
//
//        allDevelopersTabContent = new AllDevelopersTabContent();
//        addTab(allDevelopersTabContent, StringValues.ALL_MAIN_PAGE_TABS[1]);
//
//        allTasksTabContent = new AllTasksTabContent();
//        addTab(allTasksTabContent, StringValues.ALL_MAIN_PAGE_TABS[2]);
//
//        super.attach();
//    }

}
<file_sep>/pmc-web/src/main/resources/oauth.properties
oauth.callback = http://localhost:8080/pmc-web
oauth.application = facebook<file_sep>/pmc-repository/src/main/java/com/epam/app/pmc/repository/util/RepositoryUtils.java
package com.epam.app.pmc.repository.util;

import org.apache.commons.lang3.StringUtils;

import java.util.Map;
import java.util.Map.Entry;


public class RepositoryUtils {

    public static String wrapLikeParameter(String parameter) {
        return "%" + parameter + "%";
    }

    public static Map<String, String> nullifyEmpty(Map<String, String> parameters) {
        for(Entry<String, String> entry: parameters.entrySet()) {
            if (StringUtils.isBlank(entry.getValue())) {
                parameters.put(entry.getKey(), null);
            }
        }

        return parameters;
    }

    public static Map<String, String> wrapLikeParameters(Map<String, String> parameters) {
        for(Entry<String, String> entry: parameters.entrySet()) {
            if (StringUtils.isNotBlank(entry.getValue())) {
                entry.setValue(wrapLikeParameter(entry.getValue()));
            }
        }

        return parameters;
    }

}
<file_sep>/pmc-web/src/main/java/com/epam/app/pmc/vaadin/PmcServlet.java
package com.epam.app.pmc.vaadin;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import ru.xpoft.vaadin.SpringVaadinServlet;

public class PmcServlet extends SpringVaadinServlet {

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException,
            IOException {
//        SecurityContextHolder.setContext(SecurityContextHolder.createEmptyContext());

        RequestHolder.setRequest(request);

//        SecurityContextHolder.clearContext();

        super.service(request, response);
    }

}
<file_sep>/pmc-web/src/main/java/com/epam/app/pmc/vaadin/component/experimental/view/DefaultView.java
package com.epam.app.pmc.vaadin.component.experimental.view;

import com.google.common.eventbus.EventBus;
import com.vaadin.navigator.Navigator;
import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent;
import com.vaadin.ui.VerticalLayout;

public class DefaultView extends VerticalLayout implements IView {

    private Navigator navigator;

    @Override
    public void setNavigator(Navigator navigator) {
        this.navigator = navigator;
    }

    @Override
    public void enter(ViewChangeEvent event) {
        navigator.navigateTo("loginView");
    }

    @Override
    public void setEventBus(EventBus eventBus) {
        throw new UnsupportedOperationException("Not implemented for DefaulView");
    }

}
<file_sep>/pmc-service/build.gradle
dependencies {
    compile project(':pmc-repository')

    compile 'org.springframework:spring-core:4.1.1.RELEASE'
    compile 'org.springframework:spring-context:4.1.1.RELEASE'

}
<file_sep>/pmc-web/README.md
Responsible for operations with services.<file_sep>/pmc-web/src/main/java/com/epam/app/pmc/vaadin/component/modal/NewProjectModalWindow.java
package com.epam.app.pmc.vaadin.component.modal;

import com.epam.app.pmc.model.Project;
import com.epam.app.pmc.vaadin.component.experimental.NavigatorUi;
import com.epam.app.pmc.vaadin.component.tab.AllProjectsTabContent;
import com.epam.app.pmc.vaadin.component.util.DomainUtils;
import com.epam.app.pmc.vaadin.component.util.Generator;
import com.epam.app.pmc.vaadin.component.util.StringValues;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.FormLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.TextField;
import com.vaadin.ui.Window;


public class NewProjectModalWindow extends Window {

    private TextField projectName;
    private TextField projectOwner;
    private Button createProject;
    private Button cancel;

    private HorizontalLayout buttonLayout;
    private AllProjectsTabContent parentTab;

    public void setParentTab(AllProjectsTabContent parentTab) {
        this.parentTab = parentTab;
    }

    @Override
    public void attach() {
        setCaption(StringValues.NEW_PROJECT_MODAL_WINDOW_CAPTION);
        setSizeUndefined();
        setResizable(false);
        setModal(true);

        setContent(createLayout());

        super.attach();
    }

    private FormLayout createLayout() {
        FormLayout mainLayout = null;
        projectName = new TextField("Project Name");
        projectOwner = new TextField("Project owner");

        final NavigatorUi ui = (NavigatorUi) NavigatorUi.getCurrent();
        createProject = new Button("Create");
        createProject.addClickListener(new Button.ClickListener() {

            @Override
            public void buttonClick(ClickEvent event) {
                Project project = DomainUtils.createProject(projectName.getValue(), Generator.gen(), projectOwner.getValue());
                ui.getProjectService().insertProject(project);
                parentTab.updateAllProjectsTable(project);
                NewProjectModalWindow.this.close();
            }
        });

        cancel = new Button("Cancel");
        cancel.addClickListener(new Button.ClickListener() {

            @Override
            public void buttonClick(ClickEvent event) {
                NewProjectModalWindow.this.close();
            }
        });

        addCloseListener(new CloseListener(){

            @Override
            public void windowClose(CloseEvent e) {
                ui.removeWindow(NewProjectModalWindow.this);
            }

        });

        buttonLayout = new HorizontalLayout(createProject, cancel);
        mainLayout = new FormLayout(projectName, projectOwner, buttonLayout);
        mainLayout.setMargin(true);

        return mainLayout;
    }

}
