/*******************************************************************************
 * Copyright (c) 2012-2016 Codenvy, S.A.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   Codenvy, S.A. - initial API and implementation
 *******************************************************************************/
package org.eclipse.che.api.project.server;

import org.eclipse.che.api.project.shared.dto.ProjectTemplateDescriptor;

import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @author Vitaly Parfonov
 */
@Singleton
public class ProjectTemplateRegistry {

    private final Map<List<String>, List<ProjectTemplateDescriptor>> templates = new ConcurrentHashMap<>();

    public void register(List<String> tags, ProjectTemplateDescriptor template) {
        List<ProjectTemplateDescriptor> templateList = templates.get(tags);
        if (templateList == null) {
            templates.put(tags, templateList = new CopyOnWriteArrayList<>());
        }
        templateList.add(template);
    }

    public void register(List<String> tags, List<ProjectTemplateDescriptor> templates) {
        List<ProjectTemplateDescriptor> templateList = this.templates.get(tags);
        if (templateList == null) {
            this.templates.put(tags, new CopyOnWriteArrayList<>(templates));
        } else {
            templateList.addAll(templates);
        }
    }

    public List<ProjectTemplateDescriptor> getTemplates(List<String> tags) {
        List<ProjectTemplateDescriptor> templateDescriptors = new ArrayList<>();

        templates.entrySet()
                 .stream()
                 .filter(entry -> entry.getKey().containsAll(tags))
                 .forEach(entry -> templateDescriptors.addAll(entry.getValue()));

        return templateDescriptors;
    }

    public List<ProjectTemplateDescriptor> getAllTemplates() {
        List<ProjectTemplateDescriptor> allTemplates = new ArrayList<>();
        for (Map.Entry<List<String>, List<ProjectTemplateDescriptor>> entry : templates.entrySet()) {
            allTemplates.addAll(entry.getValue());
        }
        return allTemplates;
    }
}

@@ -680,23 +680,93 @@
 java
-.util.ArrayList
+x.validation.constraints.NotNull;%0Aimport java.util.ArrayList;%0Aimport java.util.Arrays
 ;%0Aim
@@ -1779,32 +1779,45 @@
        %7D%0A    %7D%0A%0A
+    @NotNull%0A
     public List%3C
@@ -1873,24 +1873,117 @@
 ng%3E tags) %7B%0A
+        if (tags == null %7C%7C tags.isEmpty()) %7B%0A            return Arrays.asList();%0A        %7D%0A%0A
         List

Fix NPE when there is no tags