gt:                 String dtoInterface = dto.getDtoInterface().getCanonicalName();
context: // Copyright 2012 Google Inc. All Rights Reserved.
  //
  // Licensed under the Apache License, Version 2.0 (the "License");
  // you may not use this file except in compliance with the License.
  // You may obtain a copy of the License at
  //
  //     http://www.apache.org/licenses/LICENSE-2.0
  //
  // Unless required by applicable law or agreed to in writing, software
  // distributed under the License is distributed on an "AS IS" BASIS,
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  // See the License for the specific language governing permissions and
  // limitations under the License.
  
  package org.eclipse.che.dto.generator;
  
  import org.eclipse.che.dto.server.DtoFactoryVisitor;
  
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.LinkedHashSet;
  import java.util.List;
  import java.util.Map;
  import java.util.Set;
  
  /**
   * Base template for the generated output file that contains all the DTOs.
   * <p/>
   * Note that we generate client and server DTOs in separate runs of the generator.
   * <p/>
   * The directionality of the DTOs only affects whether or not we expose methods to construct an instance of the DTO. We need both client and
   * server versions of all DTOs (irrespective of direction).
   */
  public class DtoTemplate {
      public static class MalformedDtoInterfaceException extends RuntimeException {
          public MalformedDtoInterfaceException(String msg) {
              super(msg);
          }
      }
  
      // We keep a whitelist of allowed non-DTO generic types.
      static final Set<Class<?>> jreWhitelist =
              new HashSet<>(Arrays.asList(new Class<?>[]{String.class, Integer.class, Double.class, Float.class, Boolean.class}));
  
      private final List<DtoImpl> dtoInterfaces = new ArrayList<>();
  
      // contains mapping for already implemented DTO interfaces
      private final Map<Class<?>, Set<Class<?>>> implementedDtoInterfaces = new HashMap<>();
  
      private final String packageName;
  
      private final String className;
  
      private final String implType;
  
      /**
       * Walks the super interface hierarchy to determine if a Class implements some target interface transitively.
       */
      static boolean implementsInterface(Class<?> i, Class<?> target) {
          if (i.equals(target)) {
              return true;
          }
  
          boolean rtn = false;
          Class<?>[] superInterfaces = i.getInterfaces();
          for (Class<?> superInterface : superInterfaces) {
              rtn = rtn || implementsInterface(superInterface, target);
          }
          return rtn;
      }
  
      /**
       * Constructor.
       *
       * @param packageName
       *         The name of the package for the outer DTO class.
       * @param className
       *         The name of the outer DTO class.
       * @param implType
       *         DTO impls type, "client" or "server".
       */
      DtoTemplate(String packageName, String className, String implType) {
          this.packageName = packageName;
          this.className = className;
          this.implType = implType;
      }
  
      public String getImplType() {
          return implType;
      }
  
      public void addImplementation(Class<?> dtoInterface, Class<?> impl) {
          Set<Class<?>> classes = implementedDtoInterfaces.get(dtoInterface);
          if (classes == null) {
              implementedDtoInterfaces.put(dtoInterface, classes = new LinkedHashSet<>());
          }
          classes.add(impl);
      }
  
      /**
       * Some DTO interfaces may be already implemented in dependencies of current project. Try to reuse them. If this method returns
       * <code>null</code> it means interface is not implemented yet.
       */
      public Class<?> getDtoImplementation(Class<?> dtoInterface) {
          Set<Class<?>> classes = implementedDtoInterfaces.get(dtoInterface);
          if (classes == null || classes.isEmpty()) {
              return null;
          }
          for (Class<?> impl : classes) {
              if (impl.getSimpleName().equals(dtoInterface.getSimpleName() + "Impl")) {
                  return impl;
              }
          }
          return null;
      }
  
      /**
       * Adds an interface to the DtoTemplate for code generation.
       *
       * @param i
       *         interface to add
       */
      public void addInterface(Class<?> i) {
          getDtoInterfaces().add(createDtoImplTemplate(i));
      }
  
      /** @return the dtoInterfaces */
      public List<DtoImpl> getDtoInterfaces() {
          return dtoInterfaces;
      }
  
      /**
       * Returns the source code for a class that contains all the DTO impls for any interfaces that were added via the {@link
       * #addInterface(Class)} method.
       */
      @Override
      public String toString() {
          StringBuilder builder = new StringBuilder();
          emitPreamble(builder);
          emitDtos(builder);
          emitPostamble(builder);
          return builder.toString();
      }
  
      /**
       * Tests whether or not a given class is a part of our dto jar, and thus will eventually have a generated Impl that is serializable
       * (thus allowing it to be a generic type).
       */
      boolean isDtoInterface(Class<?> potentialDto) {
          for (DtoImpl dto : getDtoInterfaces()) {
              if (dto.getDtoInterface().equals(potentialDto)) {
                  return true;
              }
          }
          return false;
      }
  
      private DtoImpl createDtoImplTemplate(Class<?> i) {
          if ("server".equals(implType)) {
              return new DtoImplServerTemplate(this, i);
          } else if ("client".equals(implType)) {
              return new DtoImplClientTemplate(this, i);
          }
          throw new IllegalStateException("Unsupported DTO implementation type, must be 'client' or 'server'");
      }
  
      private void emitDtos(StringBuilder builder) {
          for (DtoImpl dto : getDtoInterfaces()) {
              builder.append(dto.serialize());
          }
      }
  
      private void emitPostamble(StringBuilder builder) {
          builder.append("\n}");
      }
  
      private void emitPreamble(StringBuilder builder) {
          builder.append("/*******************************************************************************\n");
          builder.append(" * Copyright (c) 2012-2016 Codenvy, S.A.\n");
          builder.append(" * All rights reserved. This program and the accompanying materials\n");
          builder.append(" * are made available under the terms of the Eclipse Public License v1.0\n");
          builder.append(" * which accompanies this distribution, and is available at\n");
          builder.append(" * http://www.eclipse.org/legal/epl-v10.html\n");
          builder.append(" *\n");
          builder.append(" * Contributors:\n");
          builder.append(" * Codenvy, S.A. - initial API and implementation\n");
          builder.append(" *******************************************************************************/\n\n\n");
          builder.append("// GENERATED SOURCE. DO NOT EDIT.\npackage ");
          builder.append(packageName);
          builder.append(";\n\n");
          if ("server".equals(implType)) {
              builder.append("import org.eclipse.che.dto.server.JsonSerializable;\n");
              builder.append("\n");
              builder.append("import com.google.gson.Gson;\n");
              builder.append("import com.google.gson.GsonBuilder;\n");
              builder.append("import com.google.gson.JsonArray;\n");
              builder.append("import com.google.gson.JsonElement;\n");
              builder.append("import com.google.gson.JsonNull;\n");
              builder.append("import com.google.gson.JsonObject;\n");
              builder.append("import com.google.gson.JsonParser;\n");
              builder.append("import com.google.gson.JsonPrimitive;\n");
              builder.append("\n");
              builder.append("import java.util.List;\n");
              builder.append("import java.util.Map;\n");
          }
          if ("client".equals(implType)) {
              builder.append("import org.eclipse.che.ide.dto.ClientDtoFactoryVisitor;\n");
              builder.append("import org.eclipse.che.ide.dto.DtoFactoryVisitor;\n");
              builder.append("import org.eclipse.che.ide.dto.JsonSerializable;\n");
              builder.append("import com.google.gwt.json.client.*;\n");
              builder.append("import com.google.inject.Singleton;\n");
          }
          builder.append("\n\n@SuppressWarnings({\"unchecked\", \"cast\"})\n");
          if ("client".equals(implType)) {
              builder.append("@Singleton\n");
              builder.append("@ClientDtoFactoryVisitor\n");
          }
          // Note that we always use fully qualified path names when referencing Types
          // so we need not add any import statements for anything.
          builder.append("public class ");
          builder.append(className);
          if ("server".equals(implType)) {
              builder.append(" implements ").append(DtoFactoryVisitor.class.getCanonicalName());
          }
          if ("client".equals(implType)) {
              builder.append(" implements ").append("DtoFactoryVisitor");
          }
          builder.append(" {\n\n");
          if ("server".equals(implType)) {
              builder.append("  private static final Gson gson = org.eclipse.che.dto.server.DtoFactory.getInstance().getGson();\n\n");
              builder.append("  @Override\n" +
                             "  public void accept(org.eclipse.che.dto.server.DtoFactory dtoFactory) {\n");
              for (DtoImpl dto : getDtoInterfaces()) {
                  String dtoInterface = dto.getDtoInterface().getCanonicalName();
                  builder.append("    dtoFactory.registerProvider(").append(dtoInterface).append(".class").append(", ")
                         .append("new org.eclipse.che.dto.server.DtoProvider<").append(dtoInterface).append(">() {\n");
                  builder.append("        public Class<? extends ").append(dtoInterface).append("> getImplClass() {\n")
                         .append("            return ").append(dto.getImplClassName()).append(".class;\n");
                  builder.append("        }\n\n");
                  builder.append("        public ").append(dtoInterface).append(" newInstance() {\n")
                         .append("            return ").append(dto.getImplClassName()).append(".make();\n");
                  builder.append("        }\n\n");
                  builder.append("        public ").append(dtoInterface).append(" fromJson(String json) {\n")
                         .append("            return ").append(dto.getImplClassName()).append(".fromJsonString(json);\n");
                  builder.append("        }\n\n");
                  builder.append("        public ").append(dtoInterface).append(" fromJson(com.google.gson.JsonElement json) {\n")
                         .append("            return ").append(dto.getImplClassName()).append(".fromJsonElement(json);\n");
                  builder.append("        }\n\n");
                  builder.append("        public ").append(dtoInterface).append(" clone(").append(dtoInterface).append(" origin) {\n")
                         .append("            return new ").append(dto.getImplClassName()).append("(origin);\n");
                  builder.append("        }\n");
                  builder.append("    });\n");
              }
              builder.append("  }\n\n");
          }
          if ("client".equals(implType)) {
              builder.append("  @Override\n").append("  public void accept(org.eclipse.che.ide.dto.DtoFactory dtoFactory) {\n");
              for (DtoImpl dto : getDtoInterfaces()) {
  