diff --git a/include/clang/AST/ASTLambda.h b/include/clang/AST/ASTLambda.h
index 814beb34e177b9812f69aa8c1ff8f5c601c3161d..9044878e35da2977b130f6b27b135b1b7e41ba28 100644
--- a/include/clang/AST/ASTLambda.h
+++ b/include/clang/AST/ASTLambda.h
@@ -31,7 +31,13 @@ inline bool isLambdaCallOperator(const CXXMethodDecl *MD) {
   return MD->getOverloadedOperator() == OO_Call;
 }
 
+inline bool isLambdaCallOperator(const DeclContext *DC) {
+  if (!DC || !isa<CXXMethodDecl>(DC)) return false;
+  return isLambdaCallOperator(cast<CXXMethodDecl>(DC));
+}
+
 inline bool isGenericLambdaCallOperatorSpecialization(CXXMethodDecl *MD) {
+  if (!MD) return false;
   CXXRecordDecl *LambdaClass = MD->getParent();
   if (LambdaClass && LambdaClass->isGenericLambda())
     return isLambdaCallOperator(MD) && 
@@ -44,6 +50,27 @@ inline bool isGenericLambdaCallOperatorSpecialization(Decl *D) {
   return isGenericLambdaCallOperatorSpecialization(
                                 cast<CXXMethodDecl>(D));
 }
+
+inline bool isLambdaConversionOperator(CXXConversionDecl *C) {
+  return C ? C->getParent()->isLambda() : false;
+}
+
+inline bool isLambdaConversionOperator(Decl *D) {
+  if (!D) return false;
+  if (CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(D)) 
+    return isLambdaConversionOperator(Conv);  
+  if (FunctionTemplateDecl *F = dyn_cast<FunctionTemplateDecl>(D)) 
+    if (CXXConversionDecl *Conv = 
+        dyn_cast_or_null<CXXConversionDecl>(F->getTemplatedDecl())) 
+      return isLambdaConversionOperator(Conv);
+  return false;
+}
+
+inline bool isGenericLambdaCallOperatorSpecialization(DeclContext *DC) {
+  return isGenericLambdaCallOperatorSpecialization(
+                                          dyn_cast<CXXMethodDecl>(DC));
+}
+
 } // clang
 
 #endif // LLVM_CLANG_AST_LAMBDA_H
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 33c7ff99b0e5652949be79dccda6bb312041328f..146853586aca022269fe89fd5df25ed092693e22 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -972,9 +972,12 @@ CXXMethodDecl* CXXRecordDecl::getLambdaStaticInvoker() const {
   DeclContext::lookup_const_result Invoker = lookup(Name);
   if (Invoker.empty()) return 0;
   assert(Invoker.size() == 1 && "More than one static invoker operator!");  
-  CXXMethodDecl *Result = cast<CXXMethodDecl>(Invoker.front());  
-  return Result;
-
+  NamedDecl *InvokerFun = Invoker.front();
+  if (FunctionTemplateDecl *InvokerTemplate =
+                  dyn_cast<FunctionTemplateDecl>(InvokerFun)) 
+    return cast<CXXMethodDecl>(InvokerTemplate->getTemplatedDecl());
+  
+  return cast<CXXMethodDecl>(InvokerFun); 
 }
 
 void CXXRecordDecl::getCaptureFields(
@@ -1552,11 +1555,17 @@ bool CXXMethodDecl::hasInlineBody() const {
 }
 
 bool CXXMethodDecl::isLambdaStaticInvoker() const {
-  return getParent()->isLambda() && 
-         getParent()->getLambdaStaticInvoker() == this;
+  const CXXRecordDecl *P = getParent();
+  if (P->isLambda()) {
+    if (const CXXMethodDecl *StaticInvoker = P->getLambdaStaticInvoker()) {
+      if (StaticInvoker == this) return true;
+      if (P->isGenericLambda() && this->isFunctionTemplateSpecialization())
+        return StaticInvoker == this->getPrimaryTemplate()->getTemplatedDecl();
+    }
+  }
+  return false;
 }
 
-
 CXXCtorInitializer::CXXCtorInitializer(ASTContext &Context,
                                        TypeSourceInfo *TInfo, bool IsVirtual,
                                        SourceLocation L, Expr *Init,
diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp
index c1226d5681c95b0d94c662e0acbf2ffcfd451158..4db5b09afe116816b3c1155c66bbd7f6138789ec 100644
--- a/lib/CodeGen/CGClass.cpp
+++ b/lib/CodeGen/CGClass.cpp
@@ -17,6 +17,7 @@
 #include "CodeGenFunction.h"
 #include "CGCXXABI.h"
 #include "clang/AST/CXXInheritance.h"
+#include "clang/AST/DeclTemplate.h"
 #include "clang/AST/EvaluatedExprVisitor.h"
 #include "clang/AST/RecordLayout.h"
 #include "clang/AST/StmtCXX.h"
@@ -2104,14 +2105,9 @@ CodeGenFunction::EmitCXXOperatorMemberCallee(const CXXOperatorCallExpr *E,
   return CGM.GetAddrOfFunction(MD, fnType);
 }
 
-void CodeGenFunction::EmitForwardingCallToLambda(const CXXRecordDecl *lambda,
-                                                 CallArgList &callArgs) {
-  // Lookup the call operator
-  DeclarationName operatorName
-    = getContext().DeclarationNames.getCXXOperatorName(OO_Call);
-  CXXMethodDecl *callOperator =
-    cast<CXXMethodDecl>(lambda->lookup(operatorName).front());
-
+void CodeGenFunction::EmitForwardingCallToLambda(
+                                      const CXXMethodDecl *callOperator,
+                                      CallArgList &callArgs) {
   // Get the address of the call operator.
   const CGFunctionInfo &calleeFnInfo =
     CGM.getTypes().arrangeCXXMethodDeclaration(callOperator);
@@ -2162,8 +2158,9 @@ void CodeGenFunction::EmitLambdaBlockInvokeBody() {
     ParmVarDecl *param = *I;
     EmitDelegateCallArg(CallArgs, param);
   }
-
-  EmitForwardingCallToLambda(Lambda, CallArgs);
+  assert(!Lambda->isGenericLambda() && 
+            "generic lambda interconversion to block not implemented");
+  EmitForwardingCallToLambda(Lambda->getLambdaCallOperator(), CallArgs);
 }
 
 void CodeGenFunction::EmitLambdaToBlockPointerBody(FunctionArgList &Args) {
@@ -2193,8 +2190,20 @@ void CodeGenFunction::EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD) {
     ParmVarDecl *param = *I;
     EmitDelegateCallArg(CallArgs, param);
   }
-
-  EmitForwardingCallToLambda(Lambda, CallArgs);
+  const CXXMethodDecl *CallOp = Lambda->getLambdaCallOperator();
+  // For a generic lambda, find the corresponding call operator specialization
+  // to which the call to the static-invoker shall be forwarded.
+  if (Lambda->isGenericLambda()) {
+    assert(MD->isFunctionTemplateSpecialization());
+    const TemplateArgumentList *TAL = MD->getTemplateSpecializationArgs();
+    FunctionTemplateDecl *CallOpTemplate = CallOp->getDescribedFunctionTemplate();
+    void *InsertPos = 0;
+    FunctionDecl *CorrespondingCallOpSpecialization = 
+        CallOpTemplate->findSpecialization(TAL->data(), TAL->size(), InsertPos); 
+    assert(CorrespondingCallOpSpecialization);
+    CallOp = cast<CXXMethodDecl>(CorrespondingCallOpSpecialization);
+  }
+  EmitForwardingCallToLambda(CallOp, CallArgs);
 }
 
 void CodeGenFunction::EmitLambdaStaticInvokeFunction(const CXXMethodDecl *MD) {
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index 5889d058606f9522f5caf13072370358a67ced57..080d0b7b6f332672c201b857c78261e91851ea77 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -1138,7 +1138,7 @@ public:
   void emitImplicitAssignmentOperatorBody(FunctionArgList &Args);
   void EmitFunctionBody(FunctionArgList &Args);
 
-  void EmitForwardingCallToLambda(const CXXRecordDecl *Lambda,
+  void EmitForwardingCallToLambda(const CXXMethodDecl *LambdaCallOperator,
                                   CallArgList &CallArgs);
   void EmitLambdaToBlockPointerBody(FunctionArgList &Args);
   void EmitLambdaBlockInvokeBody();
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 6e1751aebd931df993730c8a5b850c7f529df7a0..4aa53e0a8e88bdd4ef64469062ccb008f58008f4 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -10351,57 +10351,92 @@ bool Sema::isImplicitlyDeleted(FunctionDecl *FD) {
   return FD->isDeleted() && FD->isDefaulted() && isa<CXXMethodDecl>(FD);
 }
 
-/// \brief Mark the call operator of the given lambda closure type as "used".
-static void markLambdaCallOperatorUsed(Sema &S, CXXRecordDecl *Lambda) {
-  CXXMethodDecl *CallOperator 
-    = cast<CXXMethodDecl>(
-        Lambda->lookup(
-          S.Context.DeclarationNames.getCXXOperatorName(OO_Call)).front());
-  CallOperator->setReferenced();
-  CallOperator->markUsed(S.Context);
-}
-
 void Sema::DefineImplicitLambdaToFunctionPointerConversion(
-       SourceLocation CurrentLocation,
-       CXXConversionDecl *Conv) 
-{
-  CXXRecordDecl *LambdaClass = Conv->getParent();
-  
-  // Make sure that the lambda call operator is marked used.
-  markLambdaCallOperatorUsed(*this, LambdaClass);
-  
-  Conv->markUsed(Context);
+                            SourceLocation CurrentLocation,
+                            CXXConversionDecl *Conv) {
+  CXXRecordDecl *Lambda = Conv->getParent();
+  CXXMethodDecl *CallOp = Lambda->getLambdaCallOperator();
+  // If we are defining a specialization of a conversion to function-ptr
+  // cache the deduced template arguments for this specialization
+  // so that we can use them to retrieve the corresponding call-operator
+  // and static-invoker. 
+  const TemplateArgumentList *DeducedTemplateArgs = 0;
+   
   
+  // Retrieve the corresponding call-operator specialization.
+  if (Lambda->isGenericLambda()) {
+    assert(Conv->isFunctionTemplateSpecialization());
+    FunctionTemplateDecl *CallOpTemplate = 
+        CallOp->getDescribedFunctionTemplate();
+    DeducedTemplateArgs = Conv->getTemplateSpecializationArgs();
+    void *InsertPos = 0;
+    FunctionDecl *CallOpSpec = CallOpTemplate->findSpecialization(
+                                                DeducedTemplateArgs->data(), 
+                                                DeducedTemplateArgs->size(), 
+                                                InsertPos);
+    assert(CallOpSpec && 
+          "Conversion operator must have a corresponding call operator");
+    CallOp = cast<CXXMethodDecl>(CallOpSpec);
+  }
+  // Mark the call operator referenced (and add to pending instantiations
+  // if necessary).
+  // For both the conversion and static-invoker template specializations
+  // we construct their body's in this function, so no need to add them
+  // to the PendingInstantiations.
+  MarkFunctionReferenced(CurrentLocation, CallOp);
+
   SynthesizedFunctionScope Scope(*this, Conv);
   DiagnosticErrorTrap Trap(Diags);
+   
+  // Retreive the static invoker...
+  CXXMethodDecl *Invoker = Lambda->getLambdaStaticInvoker();
+  // ... and get the corresponding specialization for a generic lambda.
+  if (Lambda->isGenericLambda()) {
+    assert(DeducedTemplateArgs && 
+      "Must have deduced template arguments from Conversion Operator");
+    FunctionTemplateDecl *InvokeTemplate = 
+                          Invoker->getDescribedFunctionTemplate();
+    void *InsertPos = 0;
+    FunctionDecl *InvokeSpec = InvokeTemplate->findSpecialization(
+                                                DeducedTemplateArgs->data(), 
+                                                DeducedTemplateArgs->size(), 
+                                                InsertPos);
+    assert(InvokeSpec && 
+      "Must have a corresponding static invoker specialization");
+    Invoker = cast<CXXMethodDecl>(InvokeSpec);
+  }
+  // Construct the body of the conversion function { return __invoke; }.
+  Expr *FunctionRef = BuildDeclRefExpr(Invoker, Invoker->getType(),
+                                        VK_LValue, Conv->getLocation()).take();
+   assert(FunctionRef && "Can't refer to __invoke function?");
+   Stmt *Return = ActOnReturnStmt(Conv->getLocation(), FunctionRef).take();
+   Conv->setBody(new (Context) CompoundStmt(Context, Return,
+                                            Conv->getLocation(),
+                                            Conv->getLocation()));
+
+  Conv->markUsed(Context);
+  Conv->setReferenced();
   
-  // Return the address of the __invoke function.
-  
-  CXXMethodDecl *Invoke = LambdaClass->getLambdaStaticInvoker();
-  Expr *FunctionRef = BuildDeclRefExpr(Invoke, Invoke->getType(),
-                                       VK_LValue, Conv->getLocation()).take();
-  assert(FunctionRef && "Can't refer to lambda static invoker function?");
-  Stmt *Return = ActOnReturnStmt(Conv->getLocation(), FunctionRef).take();
-  Conv->setBody(new (Context) CompoundStmt(Context, Return,
-                                           Conv->getLocation(),
-                                           Conv->getLocation()));
-    
-  // Fill in the static invoker function with a dummy implementation. 
-  // IR generation will fill in the actual details.
-  Invoke->markUsed(Context);
-  Invoke->setReferenced();
-  Invoke->setBody(new (Context) CompoundStmt(Conv->getLocation()));
-  
+  // Fill in the __invoke function with a dummy implementation. IR generation
+  // will fill in the actual details.
+  Invoker->markUsed(Context);
+  Invoker->setReferenced();
+  Invoker->setBody(new (Context) CompoundStmt(Conv->getLocation()));
+   
   if (ASTMutationListener *L = getASTMutationListener()) {
     L->CompletedImplicitDefinition(Conv);
-    L->CompletedImplicitDefinition(Invoke);
-  }
+    L->CompletedImplicitDefinition(Invoker);
+   }
 }
 
+
+
 void Sema::DefineImplicitLambdaToBlockPointerConversion(
        SourceLocation CurrentLocation,
        CXXConversionDecl *Conv) 
 {
+  assert(!Conv->getParent()->isGenericLambda());
+
   Conv->markUsed(Context);
   
   SynthesizedFunctionScope Scope(*this, Conv);
diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp
index fa46a282991c0a45fdbf901eb94497ff5b2a709d..32a385caaa559fe349bd376464e371a55758d112 100644
--- a/lib/Sema/SemaLambda.cpp
+++ b/lib/Sema/SemaLambda.cpp
@@ -857,8 +857,6 @@ static void addFunctionPointerConversion(Sema &S,
                                          SourceRange IntroducerRange,
                                          CXXRecordDecl *Class,
                                          CXXMethodDecl *CallOperator) {
-  // FIXME: The conversion operator needs to be fixed for generic lambdas.
-  if (Class->isGenericLambda()) return;
   // Add the conversion to function pointer.
   const FunctionProtoType *Proto
     = CallOperator->getType()->getAs<FunctionProtoType>(); 
@@ -898,10 +896,34 @@ static void addFunctionPointerConversion(Sema &S,
                                 CallOperator->getBody()->getLocEnd());
   Conversion->setAccess(AS_public);
   Conversion->setImplicit(true);
-  Class->addDecl(Conversion);
+
+  if (Class->isGenericLambda()) {
+    // Create a template version of the conversion operator, using the template
+    // parameter list of the function call operator.
+    FunctionTemplateDecl *TemplateCallOperator = 
+            CallOperator->getDescribedFunctionTemplate();
+    FunctionTemplateDecl *ConversionTemplate =
+                  FunctionTemplateDecl::Create(S.Context, Class,
+                                      Loc, Name,
+                                      TemplateCallOperator->getTemplateParameters(),
+                                      Conversion);
+    ConversionTemplate->setAccess(AS_public);
+    ConversionTemplate->setImplicit(true);
+    Conversion->setDescribedFunctionTemplate(ConversionTemplate);
+    Class->addDecl(ConversionTemplate);
+  } else
+    Class->addDecl(Conversion);
   // Add a non-static member function that will be the result of
   // the conversion with a certain unique ID.
   Name = &S.Context.Idents.get(getLambdaStaticInvokerName());
+  // FIXME: Instead of passing in the CallOperator->getTypeSourceInfo()
+  // we should get a prebuilt TrivialTypeSourceInfo from Context
+  // using FunctionTy & Loc and get its TypeLoc as a FunctionProtoTypeLoc
+  // then rewire the parameters accordingly, by hoisting up the InvokeParams
+  // loop below and then use its Params to set Invoke->setParams(...) below.
+  // This would avoid the 'const' qualifier of the calloperator from 
+  // contaminating the type of the invoker, which is currently adjusted 
+  // in SemaTemplateDeduction.cpp:DeduceTemplateArguments.
   CXXMethodDecl *Invoke
     = CXXMethodDecl::Create(S.Context, Class, Loc, 
                             DeclarationNameInfo(Name, Loc), FunctionTy, 
@@ -924,7 +946,19 @@ static void addFunctionPointerConversion(Sema &S,
   Invoke->setParams(InvokeParams);
   Invoke->setAccess(AS_private);
   Invoke->setImplicit(true);
-  Class->addDecl(Invoke);
+  if (Class->isGenericLambda()) {
+    FunctionTemplateDecl *TemplateCallOperator = 
+            CallOperator->getDescribedFunctionTemplate();
+    FunctionTemplateDecl *StaticInvokerTemplate = FunctionTemplateDecl::Create(
+                          S.Context, Class, Loc, Name,
+                          TemplateCallOperator->getTemplateParameters(),
+                          Invoke);
+    StaticInvokerTemplate->setAccess(AS_private);
+    StaticInvokerTemplate->setImplicit(true);
+    Invoke->setDescribedFunctionTemplate(StaticInvokerTemplate);
+    Class->addDecl(StaticInvokerTemplate);
+  } else
+    Class->addDecl(Invoke);
 }
 
 /// \brief Add a lambda's conversion to block pointer.
@@ -1096,7 +1130,9 @@ ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body,
     //   non-explicit const conversion function to a block pointer having the
     //   same parameter and return types as the closure type's function call
     //   operator.
-    if (getLangOpts().Blocks && getLangOpts().ObjC1)
+    // FIXME: Fix generic lambda to block conversions.
+    if (getLangOpts().Blocks && getLangOpts().ObjC1 && 
+                                              !Class->isGenericLambda())
       addBlockPointerConversion(*this, IntroducerRange, Class, CallOperator);
     
     // Finalize the lambda class.
@@ -1141,7 +1177,7 @@ ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body,
   }
   // TODO: Implement capturing.
   if (Lambda->isGenericLambda()) {
-    if (Lambda->getCaptureDefault() != LCD_None) {
+    if (!Captures.empty() || Lambda->getCaptureDefault() != LCD_None) {
       Diag(Lambda->getIntroducerRange().getBegin(), 
         diag::err_glambda_not_fully_implemented) 
         << " capturing not implemented yet";
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index b71aafe868addac230fbdace35a2f1804f47a903..4c73fddbb5351b3fe73f4617cddecf6ec9185030 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -13,6 +13,7 @@
 #include "clang/Sema/TemplateDeduction.h"
 #include "TreeTransform.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTLambda.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
@@ -26,7 +27,6 @@
 
 namespace clang {
   using namespace sema;
-
   /// \brief Various flags that control template argument deduction.
   ///
   /// These flags can be bitwise-OR'd together.
@@ -3607,19 +3607,37 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
   return TDK_Success;
 }
 
+/// \brief Given a function declaration (e.g. a generic lambda conversion 
+///  function) that contains an 'auto' in its result type, substitute it 
+///  with the same Deduced type that the TypeToReplaceAutoWith was deduced 
+///  with.
+static inline void 
+ReplaceAutoWithinFunctionReturnType(FunctionDecl *F, 
+                                    QualType TypeToReplaceAutoWith, Sema &S) {
+  if (TypeToReplaceAutoWith->getContainedAutoType())
+    TypeToReplaceAutoWith = TypeToReplaceAutoWith->
+        getContainedAutoType()->getDeducedType();
+
+  QualType AutoResultType = F->getResultType();
+  assert(AutoResultType->getContainedAutoType()); 
+  QualType DeducedResultType = S.SubstAutoType(AutoResultType, 
+                                               TypeToReplaceAutoWith);
+  S.Context.adjustDeducedFunctionResultType(F, DeducedResultType);
+}
 /// \brief Deduce template arguments for a templated conversion
 /// function (C++ [temp.deduct.conv]) and, if successful, produce a
 /// conversion function template specialization.
 Sema::TemplateDeductionResult
-Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
+Sema::DeduceTemplateArguments(FunctionTemplateDecl *ConversionTemplate,
                               QualType ToType,
                               CXXConversionDecl *&Specialization,
                               TemplateDeductionInfo &Info) {
-  if (FunctionTemplate->isInvalidDecl())
+  if (ConversionTemplate->isInvalidDecl())
     return TDK_Invalid;
 
   CXXConversionDecl *Conv
-    = cast<CXXConversionDecl>(FunctionTemplate->getTemplatedDecl());
+    = cast<CXXConversionDecl>(ConversionTemplate->getTemplatedDecl());
+
   QualType FromType = Conv->getConversionType();
 
   // Canonicalize the types for deduction.
@@ -3675,7 +3693,7 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
   //   type that is required as the result of the conversion (call it
   //   A) as described in 14.8.2.4.
   TemplateParameterList *TemplateParams
-    = FunctionTemplate->getTemplateParameters();
+    = ConversionTemplate->getTemplateParameters();
   SmallVector<DeducedTemplateArgument, 4> Deduced;
   Deduced.resize(TemplateParams->size());
 
@@ -3703,14 +3721,147 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
         = DeduceTemplateArgumentsByTypeMatch(*this, TemplateParams,
                                              P, A, Info, Deduced, TDF))
     return Result;
-
+
+  // Create an Instantiation Scope for finalizing the operator.
+  LocalInstantiationScope InstScope(*this);
+  
+  CXXMethodDecl *LambdaCallOpSpec = 0;
+  bool GenericLambdaCallOperatorHasDeducedReturnType = false;
+  
+  // Having successfully deduced and matched the type of the conversion
+  // function against the destination type, if the destination type
+  // is a ptr-to-function and the source type is a generic lambda conversion
+  // to ptr-to-function, we know that the parameters of the destination 
+  // ptr-to-function have matched successfully against those of our 
+  // lambda's conversion function.  
+  // For instance:
+  //  int (*fp)(int) = [](auto a) { return a; };
+  //     [template<class T> operator id<auto(*)(T)>() const]
+  // If it is indeed the conversion operator of a generic lambda then if
+  // not already done, create the corresponding specializations of the call 
+  // operator and the static-invoker; and if the return type is auto, 
+  // deduce the return type, and then check and see if it matches the ToType.
+
+  const bool IsGenericLambdaConversionOperator = 
+      isLambdaConversionOperator(Conv);
+  if (IsGenericLambdaConversionOperator) {
+    const Type *FromTypePtr = P.getTypePtr();
+    const Type *ToTypePtr = A.getTypePtr();
+
+    assert(P->isPointerType()); 
+    FromTypePtr = P->getPointeeType().getTypePtr();
+    assert(A->isPointerType());
+    ToTypePtr = A->getPointeeType().getTypePtr();
+    
+    CXXRecordDecl *LambdaClass = Conv->getParent();
+    assert(LambdaClass && LambdaClass->isGenericLambda()); 
+
+    const FunctionType *ToFunType = ToTypePtr->getAs<FunctionType>();
+
+    // The specialization of the Generic Lambda Call Op, instantiated
+    // using the deduced parameters from the conversion function
+    // i.e.
+    // auto L = [](auto a) { return f(a); };
+    // int (*fp)(int) = L;
+    //
+
+    CXXMethodDecl *CallOp = LambdaClass->getLambdaCallOperator();
+    QualType CallOpResultType = CallOp->getResultType(); 
+    GenericLambdaCallOperatorHasDeducedReturnType = 
+        CallOpResultType->getContainedAutoType();
+    FunctionTemplateDecl *CallOpTemplate = 
+        CallOp->getDescribedFunctionTemplate();
+
+    TemplateDeductionInfo OpInfo(Info.getLocation()); 
+    FunctionDecl *CallOpSpec = 0;
+    // Use the deduced arguments so far, to specialize our generic
+    // lambda's call operator.
+    if (TemplateDeductionResult Result
+                  = FinishTemplateArgumentDeduction(CallOpTemplate, Deduced, 
+                                                    0, CallOpSpec, OpInfo))
+      return Result;
+ 
+    bool HadToDeduceReturnTypeDuringCurrentCall = false;
+    // If we need to deduce the return type, do so (instantiates the callop).
+    if (GenericLambdaCallOperatorHasDeducedReturnType && 
+        CallOpSpec->getResultType()->isUndeducedType()) {
+      HadToDeduceReturnTypeDuringCurrentCall = true;
+      DeduceReturnType(CallOpSpec, CallOpSpec->getPointOfInstantiation(),
+                      /*Diagnose*/ true);
+    }
+    
+    LambdaCallOpSpec = cast<CXXMethodDecl>(CallOpSpec);
+    
+    // Check to see if the return type of the destination ptr-to-function
+    // matches the return type of the call operator.
+    if (!Context.hasSameType(LambdaCallOpSpec->getResultType(), 
+        ToFunType->getResultType()))
+      return TDK_NonDeducedMismatch;
+    // Since we have succeeded in matching the source and destination
+    // ptr-to-functions (now including return type), and have successfully 
+    // specialized our corresponding call operator, we are ready to
+    // specialize the static invoker with the deduced arguments of our
+    // ptr-to-function.
+    FunctionDecl *InvokerSpecialization = 0;
+    FunctionTemplateDecl *InvokerTemplate = LambdaClass->
+                    getLambdaStaticInvoker()->getDescribedFunctionTemplate();
+
+    TemplateDeductionResult Result
+      = FinishTemplateArgumentDeduction(InvokerTemplate, Deduced, 0, 
+            InvokerSpecialization, Info);
+    assert(Result == TDK_Success);
+    // Set the result type to match the corresponding call operator
+    // specialization's result type.
+    if (GenericLambdaCallOperatorHasDeducedReturnType && 
+        InvokerSpecialization->getResultType()->isUndeducedType())
+      ReplaceAutoWithinFunctionReturnType(InvokerSpecialization,
+                                LambdaCallOpSpec->getResultType(), *this);
+    
+    // Ensure that static invoker doesn't have a const qualifier.
+    // FIXME: When creating the InvokerTemplate in SemaLambda.cpp 
+    // do not use the CallOperator's TypeSourceInfo which allows
+    // the const qualifier to leak through. 
+    const FunctionProtoType *InvokerFPT = InvokerSpecialization->
+                    getType().getTypePtr()->castAs<FunctionProtoType>();
+    FunctionProtoType::ExtProtoInfo EPI = InvokerFPT->getExtProtoInfo();
+    EPI.TypeQuals = 0;
+    InvokerSpecialization->setType(Context.getFunctionType(
+        InvokerFPT->getResultType(), InvokerFPT->getArgTypes(),EPI));
+    
+    // Since the original conversion operator's parameters are the same 
+    // entities as the lambda's call operator's, we introduce a mapping
+    // from the generic to the specialized parameters of the call operators.
+    // This only needs to be done in the absence of return type deduction,
+    // since deducing the return type entails instantiation which adds
+    // the parameter mapping to the CurrentInstantiationScope. 
+    // This is necessary when transforming nested lambdas that do not
+    // capture.
+    // FIXME: This will be fixed once nested lambdas and capturing
+    // is implemented since it does require handling parameter 
+    // packs correctly which might require careful calls to
+    // SemaTemplateInstantiate::addInstantiatedParametersToScope.
+    // if (!HadToDeduceReturnTypeDuringCurrentCall) { ... }
+  }
+  
+  
   // Finish template argument deduction.
-  LocalInstantiationScope InstScope(*this);
-  FunctionDecl *Spec = 0;
-  TemplateDeductionResult Result
-    = FinishTemplateArgumentDeduction(FunctionTemplate, Deduced, 0, Spec,
-                                      Info);
-  Specialization = cast_or_null<CXXConversionDecl>(Spec);
+  FunctionDecl *ConversionSpec = 0;
+  TemplateDeductionResult Result
+        = FinishTemplateArgumentDeduction(ConversionTemplate, Deduced, 0, 
+              ConversionSpec, Info);
+  Specialization = cast_or_null<CXXConversionDecl>(ConversionSpec);
+  if (Result == TDK_Success && GenericLambdaCallOperatorHasDeducedReturnType) {
+    // Set the return type of the conversion specialization, since even 
+    // though we have ensured that the return types are compatible, if 
+    // there is an auto in the return type of this conversion function, 
+    // replace it permanently with the return type of the deduced lambda
+    // so we don't try and deduce against it.
+    assert(LambdaCallOpSpec);
+    if (ConversionSpec->getResultType()->isUndeducedType())
+      ReplaceAutoWithinFunctionReturnType(ConversionSpec, 
+                                          LambdaCallOpSpec->getResultType(),
+                                         *this);
+  } 
   return Result;
 }
 
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/generic-lambda-unimplemented-1y.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/generic-lambda-unimplemented-1y.cpp
index 7773aedb4ee46833922ed3c36fc821bd071bf8bc..a43a98bb18f859a939a46d630561c6d238e9e9bc 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/generic-lambda-unimplemented-1y.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/generic-lambda-unimplemented-1y.cpp
@@ -1,20 +1,30 @@
 // RUN: %clang_cc1 -fsyntax-only -std=c++1y %s -verify
-namespace return_type_deduction_ok {
- auto l = [](auto a) ->auto { return a; }(2); 
- auto l2 = [](auto a) ->decltype(auto) { return a; }(2);  
- auto l3 = [](auto a) { return a; }(2); 
-
-}
 
 namespace lambda_capturing {
 // FIXME: Once return type deduction is implemented for generic lambdas
 // this will need to be updated.
 void test() {
   int i = 10;
-  auto L = [=](auto a) -> int { //expected-error{{unimplemented}}
-    return i + a;
-  };
-  L(3); 
+  {
+    auto L = [=](auto a) -> int { //expected-error{{unimplemented}}
+      return i + a;
+    };
+    L(3);
+  }
+  {
+    auto L = [i](auto a) -> int { //expected-error{{unimplemented}}
+      return i + a;
+    };
+    L(3);
+  }  
+  {
+    auto L = [i = i](auto a) -> int { //expected-error{{unimplemented}}
+      return i + a;
+    };
+    L(3);
+  }  
+
+  
 }
 
 }
@@ -35,17 +45,4 @@ template<class T> void foo(T) {
 template void foo(int); //expected-note{{in instantiation of}}
 }
 
-namespace conversion_operator {
-void test() {
-    auto L = [](auto a) -> int { return a; };
-    int (*fp)(int) = L;  //expected-error{{no viable conversion}}
-  }
-}
-
-namespace generic_lambda_as_default_argument_ok {
-  void test(int i = [](auto a)->int { return a; }(3)) {
-  
-  }
-  
-}
 
diff --git a/test/SemaCXX/cxx1y-generic-lambdas.cpp b/test/SemaCXX/cxx1y-generic-lambdas.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b66825a536dc3939b7df65135325df5f42847984
--- /dev/null
+++ b/test/SemaCXX/cxx1y-generic-lambdas.cpp
@@ -0,0 +1,116 @@
+// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks %s
+// DONTRUNYET: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s -DDELAYED_TEMPLATE_PARSING
+// DONTRUNYET: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fms-extensions %s -DMS_EXTENSIONS
+// DONTRUNYET: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS -DDELAYED_TEMPLATE_PARSING
+
+namespace explicit_call {
+int test() {
+  auto L = [](auto a) { return a; };
+  L.operator()(3);
+  L.operator()<char>(3.14); //expected-warning{{implicit conversion}}
+  return 0;
+}  
+} //end ns
+
+namespace test_conversion_to_fptr {
+
+void f1(int (*)(int)) { }
+void f2(char (*)(int)) { } // expected-note{{candidate}}
+void g(int (*)(int)) { } // #1 expected-note{{candidate}}
+void g(char (*)(char)) { } // #2 expected-note{{candidate}}
+void h(int (*)(int)) { } // #3
+void h(char (*)(int)) { } // #4
+
+int test() {
+{
+  auto glambda = [](auto a) { return a; };
+  glambda(1);
+  f1(glambda); // OK
+  f2(glambda); // expected-error{{no matching function}}
+  g(glambda); // expected-error{{call to 'g' is ambiguous}}
+  h(glambda); // OK: calls #3 since it is convertible from ID
+  
+  int& (*fpi)(int*) = [](auto* a) -> auto& { return *a; }; // OK
+  
+}
+{
+  
+  auto L = [](auto a) { return a; };
+  int (*fp)(int) = L;
+  fp(5);
+  L(3);
+  char (*fc)(char) = L;
+  fc('b');
+  L('c');
+  double (*fd)(double) = L;
+  fd(3.14);
+  fd(6.26);
+  L(4.25);
+}
+{
+  auto L = [](auto a) ->int { return a; }; //expected-note 2{{candidate template ignored}}
+  int (*fp)(int) = L;
+  char (*fc)(char) = L; //expected-error{{no viable conversion}}
+  double (*fd)(double) = L; //expected-error{{no viable conversion}}
+}
+
+}
+
+namespace more_converion_to_ptr_to_function_tests {
+
+
+int test() {
+  {
+    int& (*fpi)(int*) = [](auto* a) -> auto& { return *a; }; // OK
+    int (*fp2)(int) = [](auto b) -> int {  return b; };
+    int (*fp3)(char) = [](auto c) -> int { return c; };
+    char (*fp4)(int) = [](auto d) { return d; }; //expected-error{{no viable conversion}}\
+                                                 //expected-note{{candidate template ignored}}
+    char (*fp5)(char) = [](auto e) -> int { return e; }; //expected-error{{no viable conversion}}\
+                                                 //expected-note{{candidate template ignored}}
+
+    fp2(3);
+    fp3('\n');
+    fp3('a');
+    return 0;
+  }
+} // end test()
+
+template<class ... Ts> void vfun(Ts ... ) { }
+
+int variadic_test() {
+
+ int (*fp)(int, char, double) = [](auto ... a) -> int { vfun(a...); return 4; };
+ fp(3, '4', 3.14);
+ 
+ int (*fp2)(int, char, double) = [](auto ... a) { vfun(a...); return 4; };
+ fp(3, '4', 3.14);
+ return 2;
+}
+
+} // end ns
+
+namespace conversion_operator {
+void test() {
+    auto L = [](auto a) -> int { return a; };
+    int (*fp)(int) = L; 
+    int (&fp2)(int) = [](auto a) { return a; };  // expected-error{{non-const lvalue}}
+    int (&&fp3)(int) = [](auto a) { return a; };  // expected-error{{no viable conversion}}\
+                                                  //expected-note{{candidate}}
+  }
+}
+
+}
+
+
+namespace return_type_deduction_ok {
+ auto l = [](auto a) ->auto { return a; }(2); 
+ auto l2 = [](auto a) ->decltype(auto) { return a; }(2);  
+ auto l3 = [](auto a) { return a; }(2); 
+
+}
+
+namespace generic_lambda_as_default_argument_ok {
+  void test(int i = [](auto a)->int { return a; }(3)) {
+  }
+}