internal static IItemContainer UnfoldTemplate(ISolution solution, IUriReferenceService uriService, IServiceProvider serviceProvider, IProductElement owner, UnfoldVsTemplateSettings settings, bool fromWizard)
        {
            var eventScope = new StoreEventBufferingScope();

            try
            {
                Guard.NotNull(() => solution, solution);
                Guard.NotNull(() => owner, owner);
                Guard.NotNull(() => settings, settings);

                var pathHelper  = new UnfoldPathHelper(solution);
                var templateUri = new Uri(settings.TemplateUri);

                // Resolve the designtime template
                tracer.Verbose(
                    Resources.UnfoldVsTemplateCommand_TraceResolvingTemplateUri, owner, settings.TemplateUri.ToString());
                var template = uriService.TryResolveUri <ITemplate>(templateUri);
                if (template == null)
                {
                    throw new FileNotFoundException(
                              string.Format(CultureInfo.CurrentCulture,
                                            Resources.UnfoldVsTemplateCommand_ErrorTemplateNotFound, templateUri), settings.TemplateUri.ToString());
                }

                // Resolve the vstemplate
                tracer.Verbose(
                    Resources.UnfoldVsTemplateCommand_TraceResolvingVsTemplateUri, owner, templateUri);
                var vsTemplate = uriService.ResolveUri <IVsTemplate>(templateUri);

                // Get the resolved instance name for the unfolded item
                var unfoldResolver = new UnfoldParentResolver(solution, uriService, owner, vsTemplate);
                unfoldResolver.ResolveParent(settings.TargetPath, settings.TargetFileName);
                var instanceName = unfoldResolver.FileName;
                if (settings.SanitizeName)
                {
                    instanceName = DataFormats.MakePreferredSolutionItemName(instanceName);
                }

                // Ensure name is unique (on disk)
                var solutionItemName = pathHelper.GetUniqueName(instanceName, vsTemplate, unfoldResolver.ParentItem);

                //TODO: We need to close the existing solution (if any) if template is a ProjectGroup
                // if (vsTemplate.Type == VsTemplateType.ProjectGroup).
                // Otherwise this will fail the unfold

                // Unfold the template
                var generatedItem = template.Unfold(unfoldResolver.ResolveExtension(solutionItemName), unfoldResolver.ParentItem);
                eventScope.Dispose();

                // Perhaps the template unfolded multiple items and none was identifed as the primary
                // (such as in a multi-item item template, with no non-fixed named items)
                if (generatedItem != null)
                {
                    // Prompt user to update element instance name (on name collision) if he is synching names,
                    // it doesn't make sense to correlate them otherwise
                    if (settings.SyncName)
                    {
                        if (!instanceName.Equals(solutionItemName, StringComparison.OrdinalIgnoreCase))
                        {
                            if (serviceProvider != null)
                            {
                                var shellService = serviceProvider.GetService <IVsUIShell>();
                                if (shellService != null)
                                {
                                    var result = shellService.ShowPrompt(
                                        Resources.UnfoldVsTemplateCommand_PromptToSyncNameTitle,
                                        string.Format(CultureInfo.CurrentCulture,
                                                      Resources.UnfoldVsTemplateCommand_PromptToSyncName,
                                                      instanceName, solutionItemName));
                                    if (result)
                                    {
                                        owner.InstanceName = solutionItemName;
                                    }
                                }
                                else
                                {
                                    owner.InstanceName = solutionItemName;
                                }
                            }
                            else
                            {
                                owner.InstanceName = solutionItemName;
                            }
                        }
                    }

                    if (!fromWizard)
                    {
                        tracer.Info(
                            Resources.UnfoldVsTemplateCommand_TraceAddReference, owner);

                        SolutionArtifactLinkReference
                        .AddReference(owner, uriService.CreateUri(generatedItem))
                        .Tag = BindingSerializer.Serialize(new ReferenceTag
                        {
                            Tag            = settings.Tag ?? string.Empty,
                            SyncNames      = settings.SyncName,
                            TargetFileName = settings.TargetFileName
                        });
                    }
                }
                return(generatedItem);
            }
            catch (WizardBackoutException) //cancel the unfold if wizard backout
            {
                tracer.Info(
                    Resources.UnfoldVsTemplateCommand_TraceWizardCancelled);
                owner.Delete();
                eventScope.Dispose();
                return(null);
            }
            catch (COMException comEx)
            {
                tracer.Error(
                    comEx, Resources.UnfoldVsTemplateCommand_TraceCOMException, owner.InstanceName, settings.TemplateUri);
                owner.Delete();
                eventScope.Dispose();
                throw;
            }
            catch (OperationCanceledException)
            {
                // This exception can be throw explicitly by author code
                // that wishes to cancel execution, with a friendly user
                // message, so we can pass this on as-is.
                throw;
            }
            catch (Exception ex) //cancel the unfold if another unexpected exception happened
            {
                tracer.Info(
                    Resources.UnfoldVsTemplateCommand_TraceUnexpectedException, owner.InstanceName, settings.TemplateUri);
                owner.Delete();
                eventScope.Dispose();

                throw new OperationCanceledException(string.Format(
                                                         CultureInfo.CurrentCulture,
                                                         Resources.UnfoldVsTemplateCommand_UnexpectedException,
                                                         settings.TemplateUri, owner.InstanceName, ex.Message));
            }
        }
        internal static IItemContainer UnfoldTemplate(ISolution solution, IUriReferenceService uriService, IServiceProvider serviceProvider, IProductElement owner, UnfoldVsTemplateSettings settings, bool fromWizard)
        {
            var eventScope = new StoreEventBufferingScope();
            try
            {
                Guard.NotNull(() => solution, solution);
                Guard.NotNull(() => owner, owner);
                Guard.NotNull(() => settings, settings);

                var pathHelper = new UnfoldPathHelper(solution);
                var templateUri = new Uri(settings.TemplateUri);

                // Resolve the designtime template
                tracer.Verbose(
                    Resources.UnfoldVsTemplateCommand_TraceResolvingTemplateUri, owner, settings.TemplateUri.ToString());
                var template = uriService.TryResolveUri<ITemplate>(templateUri);
                if (template == null)
                {
                    throw new FileNotFoundException(
                        string.Format(CultureInfo.CurrentCulture,
                        Resources.UnfoldVsTemplateCommand_ErrorTemplateNotFound, templateUri), settings.TemplateUri.ToString());
                }

                // Resolve the vstemplate
                tracer.Verbose(
                    Resources.UnfoldVsTemplateCommand_TraceResolvingVsTemplateUri, owner, templateUri);
                var vsTemplate = uriService.ResolveUri<IVsTemplate>(templateUri);

                // Get the resolved instance name for the unfolded item
                var unfoldResolver = new UnfoldParentResolver(solution, uriService, owner, vsTemplate);
                unfoldResolver.ResolveParent(settings.TargetPath, settings.TargetFileName);
                var instanceName = unfoldResolver.FileName;
                if (settings.SanitizeName)
                {
                    instanceName = DataFormats.MakePreferredSolutionItemName(instanceName);
                }

                // Ensure name is unique (on disk)
                var solutionItemName = pathHelper.GetUniqueName(instanceName, vsTemplate, unfoldResolver.ParentItem);

                //TODO: We need to close the existing solution (if any) if template is a ProjectGroup 
                // if (vsTemplate.Type == VsTemplateType.ProjectGroup).
                // Otherwise this will fail the unfold

                // Unfold the template
                var generatedItem = template.Unfold(unfoldResolver.ResolveExtension(solutionItemName), unfoldResolver.ParentItem);
                eventScope.Dispose();

                // Perhaps the template unfolded multiple items and none was identifed as the primary
                // (such as in a multi-item item template, with no non-fixed named items)
                if (generatedItem != null)
                {
                    // Prompt user to update element instance name (on name collision) if he is synching names, 
                    // it doesn't make sense to correlate them otherwise
                    if (settings.SyncName)
                    {
                        if (!instanceName.Equals(solutionItemName, StringComparison.OrdinalIgnoreCase))
                        {
                            if (serviceProvider != null)
                            {
                                var shellService = serviceProvider.GetService<IVsUIShell>();
                                if (shellService != null)
                                {
                                    var result = shellService.ShowPrompt(
                                        Resources.UnfoldVsTemplateCommand_PromptToSyncNameTitle,
                                        string.Format(CultureInfo.CurrentCulture,
                                            Resources.UnfoldVsTemplateCommand_PromptToSyncName,
                                            instanceName, solutionItemName));
                                    if (result)
                                    {
                                        owner.InstanceName = solutionItemName;
                                    }
                                }
                                else
                                {
                                    owner.InstanceName = solutionItemName;
                                }
                            }
                            else
                            {
                                owner.InstanceName = solutionItemName;
                            }
                        }
                    }

                    if (!fromWizard)
                    {
                        tracer.Info(
                            Resources.UnfoldVsTemplateCommand_TraceAddReference, owner);

                        SolutionArtifactLinkReference
                            .AddReference(owner, uriService.CreateUri(generatedItem))
                            .Tag = BindingSerializer.Serialize(new ReferenceTag
                        {
                            Tag = settings.Tag ?? string.Empty,
                            SyncNames = settings.SyncName,
                            TargetFileName = settings.TargetFileName
                        });
                    }
                }
                return generatedItem;
            }
            catch (WizardBackoutException) //cancel the unfold if wizard backout
            {
                tracer.Info(
                    Resources.UnfoldVsTemplateCommand_TraceWizardCancelled);
                owner.Delete();
                eventScope.Dispose();
                return null;
            }
            catch (COMException comEx)
            {
                tracer.Error(
                    comEx, Resources.UnfoldVsTemplateCommand_TraceCOMException, owner.InstanceName, settings.TemplateUri);
                owner.Delete();
                eventScope.Dispose();
                throw;
            }
            catch (OperationCanceledException)
            {
                // This exception can be throw explicitly by author code 
                // that wishes to cancel execution, with a friendly user 
                // message, so we can pass this on as-is.
                throw;
            }
            catch (Exception ex) //cancel the unfold if another unexpected exception happened
            {
                tracer.Info(
                    Resources.UnfoldVsTemplateCommand_TraceUnexpectedException, owner.InstanceName, settings.TemplateUri);
                owner.Delete();
                eventScope.Dispose();

                throw new OperationCanceledException(string.Format(
                    CultureInfo.CurrentCulture,
                    Resources.UnfoldVsTemplateCommand_UnexpectedException,
                    settings.TemplateUri, owner.InstanceName, ex.Message));
            }
        }