// Path: src/main/java/org/gwtproject/place/shared/PlaceHistoryMapper.java
// public interface PlaceHistoryMapper {
// 
//   /**
//    * Returns the {@link Place} associated with the given token.
//    *
//    * @param token a String token
//    * @return a {@link Place} instance
//    */
//   Place getPlace(String token);
// 
//   /**
//    * Returns the String token associated with the given {@link Place}.
//    *
//    * @param place a {@link Place} instance
//    * @return a String token
//    */
//   String getToken(Place place);
// }
// 
// Path: src/main/java/org/gwtproject/place/shared/PlaceTokenizer.java
// public interface PlaceTokenizer<P extends Place> {
// 
//   /**
//    * Returns the {@link Place} associated with the given token.
//    *
//    * @param token a String token
//    * @return a {@link Place} of type P
//    */
//   P getPlace(String token);
// 
//   /**
//    * Returns the token associated with the given {@link Place}.
//    *
//    * @param place a {@link Place} of type P
//    * @return a String token
//    */
//   String getToken(P place);
// }


import com.google.auto.common.AnnotationMirrors;
import com.google.auto.common.MoreElements;
import com.google.auto.common.MoreTypes;
import com.squareup.javapoet.ClassName;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.TreeMap;
import java.util.stream.Collectors;
import javax.annotation.processing.Messager;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.ExecutableType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import javax.tools.Diagnostic;
import org.gwtproject.place.shared.PlaceHistoryMapper;
import org.gwtproject.place.shared.PlaceTokenizer;
import org.gwtproject.place.shared.Prefix;
import org.gwtproject.place.shared.WithFactory;
import org.gwtproject.place.shared.WithTokenizers;
            String.format(
                "Found duplicate tokenizer\'s place type \"%s\" on %s, already seen on %s",
                placeType.getQualifiedName(),
                this.getLogMessage(tokenizerClassOrGetter),
                this.getLogMessage(this.tokenizers.get(this.placeTypes.get(placeType)))),
            tokenizerClassOrGetter);
      } else {
        this.tokenizers.put(prefix, tokenizerClassOrGetter);
        this.placeTypes.put(placeType, prefix);
      }
    }
  }

  private String getLogMessage(Element methodOrClass) {
    switch (methodOrClass.getKind()) {
      case METHOD:
        return ((TypeElement) methodOrClass.getEnclosingElement()).getQualifiedName()
            + "#"
            + methodOrClass.getSimpleName()
            + "()";
      case CLASS:
        return ((TypeElement) methodOrClass).getQualifiedName().toString();
      default:
        throw new AssertionError();
    }
  }

  private TypeElement getPlaceTypeForTokenizerType(DeclaredType tokenizerType) {
    TypeMirror placeType =
        types.asMemberOf(tokenizerType, this.placeTokenizerType.getTypeParameters().get(0));
// Path: src/main/java/org/gwtproject/place/shared/PlaceHistoryMapper.java
// public interface PlaceHistoryMapper {
// 
//   /**
//    * Returns the {@link Place} associated with the given token.
//    *
//    * @param token a String token
//    * @return a {@link Place} instance
//    */
//   Place getPlace(String token);
// 
//   /**
//    * Returns the String token associated with the given {@link Place}.
//    *
//    * @param place a {@link Place} instance
//    * @return a String token
//    */
//   String getToken(Place place);
// }
// 
// Path: src/main/java/org/gwtproject/place/shared/PlaceTokenizer.java
// public interface PlaceTokenizer<P extends Place> {
// 
//   /**
//    * Returns the {@link Place} associated with the given token.
//    *
//    * @param token a String token
//    * @return a {@link Place} of type P
//    */
//   P getPlace(String token);
// 
//   /**
//    * Returns the token associated with the given {@link Place}.
//    *
//    * @param place a {@link Place} of type P
//    * @return a String token
//    */
//   String getToken(P place);
// }


// Path: processor/src/main/java/org/gwtproject/place/processor/PlaceHistoryGeneratorContext.java
import com.google.auto.common.AnnotationMirrors;
import com.google.auto.common.MoreElements;
import com.google.auto.common.MoreTypes;
import com.squareup.javapoet.ClassName;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.TreeMap;
import java.util.stream.Collectors;
import javax.annotation.processing.Messager;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.ExecutableType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import javax.tools.Diagnostic;
import org.gwtproject.place.shared.PlaceHistoryMapper;
import org.gwtproject.place.shared.PlaceTokenizer;
import org.gwtproject.place.shared.Prefix;
import org.gwtproject.place.shared.WithFactory;
import org.gwtproject.place.shared.WithTokenizers;

            String.format(
                "Found duplicate tokenizer\'s place type \"%s\" on %s, already seen on %s",
                placeType.getQualifiedName(),
                this.getLogMessage(tokenizerClassOrGetter),
                this.getLogMessage(this.tokenizers.get(this.placeTypes.get(placeType)))),
            tokenizerClassOrGetter);
      } else {
        this.tokenizers.put(prefix, tokenizerClassOrGetter);
        this.placeTypes.put(placeType, prefix);
      }
    }
  }

  private String getLogMessage(Element methodOrClass) {
    switch (methodOrClass.getKind()) {
      case METHOD:
        return ((TypeElement) methodOrClass.getEnclosingElement()).getQualifiedName()
            + "#"
            + methodOrClass.getSimpleName()
            + "()";
      case CLASS:
        return ((TypeElement) methodOrClass).getQualifiedName().toString();
      default:
        throw new AssertionError();
    }
  }

  private TypeElement getPlaceTypeForTokenizerType(DeclaredType tokenizerType) {
    TypeMirror placeType =
        types.asMemberOf(tokenizerType, this.placeTokenizerType.getTypeParameters().get(0));
    if (placeType.getKind() != TypeKind.DECLARED) {