// Path: src/org/emberjs/codeInsight/EmberJSTypeEvaluator.java
// public class EmberJSTypeEvaluator extends JSTypeEvaluator {
//     public EmberJSTypeEvaluator(BaseJSSymbolProcessor.EvaluateContext context,
//                                   BaseJSSymbolProcessor.TypeProcessor processor, boolean ecma) {
//         super(context, processor, ecma);
//     }
// 
//     @Override
//     protected boolean addTypeFromElementResolveResult(JSReferenceExpression expression,
//                                                       PsiElement parent,
//                                                       PsiElement resolveResult,
//                                                       boolean wasProtoType,
//                                                       boolean hasSomeType) {
//         if (resolveResult instanceof JSDefinitionExpression) {
//             final PsiElement resolveParent = resolveResult.getParent();
//             if (resolveParent instanceof EmberJSAsExpression) {
//                 final String name = resolveParent.getFirstChild().getText();
//                 final JSTypeSource source = JSTypeSourceFactory.createTypeSource(resolveResult);
//                 final JSType type = JSNamedType.createType(name, source, JSNamedType.StaticOrInstance.INSTANCE);
//                 addType(type, resolveResult);
//                 return true;
//             } else if (resolveParent instanceof EmberJSRepeatExpression) {
//                 if (calculateRepeatParameterType((EmberJSRepeatExpression)resolveParent)) {
//                     return true;
//                 }
//             }
//         }
//         if (resolveResult instanceof JSParameter &&
//                 EmberIndexUtil.hasEmberJS(resolveResult.getProject())) {
//             final String name = ((JSParameter)resolveResult).getName();
//             final JSTypeSource source = JSTypeSourceFactory.createTypeSource(resolveResult);
//             final JSType type = JSNamedType.createType(name, source, JSNamedType.StaticOrInstance.INSTANCE);
//             addType(type, resolveResult);
//         }
//         return super.addTypeFromElementResolveResult(expression, parent, resolveResult, wasProtoType, hasSomeType);
//     }
// 
//     // does Ember have any equivalent of this?
//     private boolean calculateRepeatParameterType(EmberJSRepeatExpression resolveParent) {
//         final PsiElement last = findReferenceExpression(resolveParent);
//         JSType arrayType = null;
//         if (last instanceof JSReferenceExpression) {
//             PsiElement resolve = ((JSReferenceExpression)last).resolve();
//             resolve = resolve instanceof JSNamedElementProxy ? ((JSNamedElementProxy)resolve).getElement() : resolve;
//             resolve = resolve instanceof JSVariable ? ((JSVariable)resolve).getInitializer() : resolve;
//             if (resolve instanceof JSExpression) {
//                 arrayType = evalExprType((JSExpression)resolve);
//             }
//         } else if (last instanceof JSExpression) {
//             arrayType = evalExprType((JSExpression)last);
//         }
//         final JSType elementType = findElementType(arrayType);
//         if (elementType != null) {
//             addType(elementType, null);
//             return true;
//         }
//         return false;
//     }
// 
//     private static JSType findElementType(JSType type) {
//         if (type instanceof JSArrayTypeImpl) {
//             return ((JSArrayTypeImpl)type).getType();
//         }
//         if (type instanceof JSCompositeTypeImpl) {
//             for (JSType jsType : ((JSCompositeTypeImpl)type).getTypes()) {
//                 final JSType elementType = findElementType(jsType);
//                 if (elementType != null) {
//                     return elementType;
//                 }
//             }
//         }
//         return null;
//     }
// 
//     private static PsiElement findReferenceExpression(EmberJSRepeatExpression parent) {
//         JSExpression collection = parent.getCollection();
//         // do stuff??
//         return collection;
//     }
// }


import com.intellij.lang.javascript.JavaScriptSpecificHandlersFactory;
import com.intellij.lang.javascript.psi.impl.JSReferenceExpressionImpl;
import com.intellij.lang.javascript.psi.resolve.BaseJSSymbolProcessor;
import com.intellij.lang.javascript.psi.resolve.JSResolveUtil;
import com.intellij.lang.javascript.psi.resolve.JSTypeEvaluator;
import com.intellij.psi.PsiFile;
import org.emberjs.codeInsight.EmberJSTypeEvaluator;
import org.jetbrains.annotations.NotNull;
package org.emberjs.codeInsight;


/**
 * @author Dennis.Ushakov
 */
public class EmberJSSpecificHandlersFactory extends JavaScriptSpecificHandlersFactory {
    @NotNull
    @Override
    public JSResolveUtil.Resolver<JSReferenceExpressionImpl> createReferenceExpressionResolver(JSReferenceExpressionImpl referenceExpression,
                                                                                               PsiFile containingFile) {
        return new EmberJSReferenceExpressionResolver(referenceExpression, containingFile);
    }

    @NotNull
    @Override
    public JSTypeEvaluator newTypeEvaluator(BaseJSSymbolProcessor.EvaluateContext context,
                                            BaseJSSymbolProcessor.TypeProcessor processor,
                                            boolean ecma) {
// Path: src/org/emberjs/codeInsight/EmberJSTypeEvaluator.java
// public class EmberJSTypeEvaluator extends JSTypeEvaluator {
//     public EmberJSTypeEvaluator(BaseJSSymbolProcessor.EvaluateContext context,
//                                   BaseJSSymbolProcessor.TypeProcessor processor, boolean ecma) {
//         super(context, processor, ecma);
//     }
// 
//     @Override
//     protected boolean addTypeFromElementResolveResult(JSReferenceExpression expression,
//                                                       PsiElement parent,
//                                                       PsiElement resolveResult,
//                                                       boolean wasProtoType,
//                                                       boolean hasSomeType) {
//         if (resolveResult instanceof JSDefinitionExpression) {
//             final PsiElement resolveParent = resolveResult.getParent();
//             if (resolveParent instanceof EmberJSAsExpression) {
//                 final String name = resolveParent.getFirstChild().getText();
//                 final JSTypeSource source = JSTypeSourceFactory.createTypeSource(resolveResult);
//                 final JSType type = JSNamedType.createType(name, source, JSNamedType.StaticOrInstance.INSTANCE);
//                 addType(type, resolveResult);
//                 return true;
//             } else if (resolveParent instanceof EmberJSRepeatExpression) {
//                 if (calculateRepeatParameterType((EmberJSRepeatExpression)resolveParent)) {
//                     return true;
//                 }
//             }
//         }
//         if (resolveResult instanceof JSParameter &&
//                 EmberIndexUtil.hasEmberJS(resolveResult.getProject())) {
//             final String name = ((JSParameter)resolveResult).getName();
//             final JSTypeSource source = JSTypeSourceFactory.createTypeSource(resolveResult);
//             final JSType type = JSNamedType.createType(name, source, JSNamedType.StaticOrInstance.INSTANCE);
//             addType(type, resolveResult);
//         }
//         return super.addTypeFromElementResolveResult(expression, parent, resolveResult, wasProtoType, hasSomeType);
//     }
// 
//     // does Ember have any equivalent of this?
//     private boolean calculateRepeatParameterType(EmberJSRepeatExpression resolveParent) {
//         final PsiElement last = findReferenceExpression(resolveParent);
//         JSType arrayType = null;
//         if (last instanceof JSReferenceExpression) {
//             PsiElement resolve = ((JSReferenceExpression)last).resolve();
//             resolve = resolve instanceof JSNamedElementProxy ? ((JSNamedElementProxy)resolve).getElement() : resolve;
//             resolve = resolve instanceof JSVariable ? ((JSVariable)resolve).getInitializer() : resolve;
//             if (resolve instanceof JSExpression) {
//                 arrayType = evalExprType((JSExpression)resolve);
//             }
//         } else if (last instanceof JSExpression) {
//             arrayType = evalExprType((JSExpression)last);
//         }
//         final JSType elementType = findElementType(arrayType);
//         if (elementType != null) {
//             addType(elementType, null);
//             return true;
//         }
//         return false;
//     }
// 
//     private static JSType findElementType(JSType type) {
//         if (type instanceof JSArrayTypeImpl) {
//             return ((JSArrayTypeImpl)type).getType();
//         }
//         if (type instanceof JSCompositeTypeImpl) {
//             for (JSType jsType : ((JSCompositeTypeImpl)type).getTypes()) {
//                 final JSType elementType = findElementType(jsType);
//                 if (elementType != null) {
//                     return elementType;
//                 }
//             }
//         }
//         return null;
//     }
// 
//     private static PsiElement findReferenceExpression(EmberJSRepeatExpression parent) {
//         JSExpression collection = parent.getCollection();
//         // do stuff??
//         return collection;
//     }
// }


// Path: src/org/emberjs/codeInsight/EmberJSSpecificHandlersFactory.java
import com.intellij.lang.javascript.JavaScriptSpecificHandlersFactory;
import com.intellij.lang.javascript.psi.impl.JSReferenceExpressionImpl;
import com.intellij.lang.javascript.psi.resolve.BaseJSSymbolProcessor;
import com.intellij.lang.javascript.psi.resolve.JSResolveUtil;
import com.intellij.lang.javascript.psi.resolve.JSTypeEvaluator;
import com.intellij.psi.PsiFile;
import org.emberjs.codeInsight.EmberJSTypeEvaluator;
import org.jetbrains.annotations.NotNull;

package org.emberjs.codeInsight;


/**
 * @author Dennis.Ushakov
 */
public class EmberJSSpecificHandlersFactory extends JavaScriptSpecificHandlersFactory {
    @NotNull
    @Override
    public JSResolveUtil.Resolver<JSReferenceExpressionImpl> createReferenceExpressionResolver(JSReferenceExpressionImpl referenceExpression,
                                                                                               PsiFile containingFile) {
        return new EmberJSReferenceExpressionResolver(referenceExpression, containingFile);
    }

    @NotNull
    @Override
    public JSTypeEvaluator newTypeEvaluator(BaseJSSymbolProcessor.EvaluateContext context,
                                            BaseJSSymbolProcessor.TypeProcessor processor,
                                            boolean ecma) {
        return new EmberJSTypeEvaluator(context, processor, ecma);