@NotNull
  public static LookupElement toLookupElement(OperationChain chain,
                                              ChainCompletionContext context) {
    int unreachableParametersCount = 0;
    int matchedParametersInContext = 0;
    LookupElement chainLookupElement = null;

    for (ChainOperation op : chain.getPath()) {
      if (op instanceof ChainOperation.MethodCall) {
        PsiMethod method = Objects
          .requireNonNull(MethodChainsSearchUtil.getMethodWithMinNotPrimitiveParameters(((ChainOperation.MethodCall)op).getCandidates(),
                                                                                        context.getTarget().getTargetClass()));
        Couple<Integer> info = calculateParameterInfo(method, context);
        unreachableParametersCount += info.getFirst();
        matchedParametersInContext += info.getSecond();

        if (chainLookupElement == null) {
          LookupElement qualifierLookupElement = method.hasModifierProperty(PsiModifier.STATIC) ? null : createQualifierLookupElement(chain.getQualifierClass(), context);
          LookupElement headLookupElement = createMethodLookupElement(method);
          chainLookupElement = qualifierLookupElement == null ? headLookupElement : new JavaChainLookupElement(qualifierLookupElement, headLookupElement);
        } else {
          chainLookupElement = new JavaChainLookupElement(chainLookupElement, new JavaMethodCallElement(method));
        }
      } else {
        if (chainLookupElement == null) {
          chainLookupElement = createQualifierLookupElement(chain.getQualifierClass(), context);
        }
        PsiClass castClass = ((ChainOperation.TypeCast)op).getCastClass();
        PsiClassType type = JavaPsiFacade.getElementFactory(castClass.getProject()).createType(castClass);
        chainLookupElement = PrioritizedLookupElement.withPriority(CastingLookupElementDecorator.createCastingElement(chainLookupElement, type), -1);
      }
    }

    if (context.getTarget().isIteratorAccess()) {
      chainLookupElement = decorateWithIteratorAccess(chain.getFirst()[0], chainLookupElement);
    }

    return new JavaRelevantChainLookupElement(Objects.requireNonNull(chainLookupElement),
                                              new ChainRelevance(chain.length(), unreachableParametersCount, matchedParametersInContext));
  }
@NotNull
  public static LookupElement toLookupElement(OperationChain chain,
                                              ChainCompletionContext context)