private Map<String, Type> parseRepeatScope(PageCompilingContext pc, String[] extract, Node node) {
    RepeatToken repeat = registry.parseRepeat(extract[1]);
    Map<String, Type> context = Maps.newHashMap();

    // Verify that @Repeat was parsed correctly.
    if (null == repeat.var()) {
      pc.errors.add(
          CompileError.in(node.outerHtml())
              .near(node.siblingIndex()) // TODO - line number
              .causedBy(CompileErrors.MISSING_REPEAT_VAR));
    }
    if (null == repeat.items()) {
      pc.errors.add(
          CompileError.in(node.outerHtml())
              .near(node.siblingIndex()) // TODO  - line number
              .causedBy(CompileErrors.MISSING_REPEAT_ITEMS));
    }

    try {
      Type egressType = pc.lexicalScopes.peek().resolveEgressType(repeat.items());

      // convert to collection if we need to
      Type elementType;
      Class<?> egressClass = Generics.erase(egressType);
      if (egressClass.isArray()) {
        elementType = Generics.getArrayComponentType(egressType);
      } else if (Collection.class.isAssignableFrom(egressClass)) {
        elementType =
            Generics.getTypeParameter(egressType, Collection.class.getTypeParameters()[0]);
      } else {
        pc.errors.add(
            CompileError.in(node.outerHtml())
                .near(node.siblingIndex()) // TODO - line number
                .causedBy(CompileErrors.REPEAT_OVER_ATOM));
        return Collections.emptyMap();
      }

      context.put(repeat.var(), elementType);
      context.put(repeat.pageVar(), pc.page);
      context.put("__page", pc.page);
      context.put("index", int.class);
      context.put("isLast", boolean.class);

    } catch (ExpressionCompileException e) {
      pc.errors.add(
          CompileError.in(node.outerHtml())
              .near(node.siblingIndex()) // TODO - line number
              .causedBy(e));
    }

    return context;
  }
 private void registerMvelHandler(Type targetType) {
   Class<?> targetClass = Generics.erase(targetType);
   SitebricksConversionHandler targetHandler = new SitebricksConversionHandler(targetType);
   DataConversion.addConversionHandler(targetClass, targetHandler);
   if (Primitives.isWrapperType(targetClass)) {
     DataConversion.addConversionHandler(Primitives.unwrap(targetClass), targetHandler);
   }
 }
  @Inject
  public void prepare(ConverterRegistry registry, TypeConverter delegate) {
    this.registry = registry;
    this.delegate = delegate;

    Collection<Converter<?, ?>> converters = registry.getConvertersBySource().values();
    for (Converter<?, ?> converter : converters) {
      ParameterizedType converterType =
          (ParameterizedType) Generics.getExactSuperType(converter.getClass(), Converter.class);

      Type[] converterParameters = converterType.getActualTypeArguments();
      registerMvelHandler(converterParameters[0]);
      registerMvelHandler(converterParameters[1]);
    }
  }