     callback ?= ->
     options  ?= {}
 
-    fetchStackTemplate client, (err, res)->
+    fetchGroupStackTemplate client, (err, res) ->
 
       return callback err  if err
 
-      { account, user, group, template } = res
-
-      stackRevision = template.template?.sum or ''
-
-      JComputeStack = require '../stack'
-      JComputeStack.create {
-        title         : template.title
-        config        : template.config
-        baseStackId   : template._id
-        groupSlug     : group.slug
-        account, stackRevision
-      }, (err, stack)->
-
+      {template, account} = res
+      checkTemplateUsage template, account, (err) ->
         return callback err  if err
 
-        queue         = []
-        results       =
-          rules       : []
-          machines    : []
-          domains     : []
-          connections : []
-
-        queue.push ->
-
-          checkTemplateUsage template, account, (err)->
-            return callback err  if err
-
-            account.addStackTemplate template, (err)->
-              if err then callback err else queue.next()
-
-        template.machines?.forEach (machineInfo)->
-
-          queue.push ->
-
-            machineInfo.stack         = stack
-
-            # We are passing the provided credential for the template
-            # Provider implementation can override this value like we
-            # did in Koding Provider ~ GG
-            machineInfo.credential    = template.credentials?.first
-            machineInfo.generatedFrom =
-              templateId : template._id
-              revision   : stackRevision
-
-            create = (machineInfo) ->
-              ComputeProvider.create client, machineInfo, (err, machine)->
-                results.machines.push { err, obj: machine }
-                queue.next()
-
-            # This is optional, since for koding group for example
-            # we don't want to add our admins into users machines ~ GG
-            unless options.addGroupAdminToMachines
-              return create machineInfo
-
-            # TODO Do we need all admins or only some of them? ~ GG
-            # Maybe some of them as admin some of them as user etc.
-            group.fetchAdmin (err, admin)->
-
-              if not err and admin and not admin.getId().equals account.getId()
-                admin.fetchUser (err, adminUser)->
-                  if not err and adminUser
-                    machineInfo.users = [
-                      { id: adminUser.getId(), sudo: yes, owner: yes }
-                    ]
-                  create machineInfo
-              else
-                create machineInfo
-
-
-        template.domains?.forEach (domainInfo)->
-
-          queue.push ->
-            domain = domainInfo.domain.replace "${username}", user.username
-            JProposedDomain.createDomain {
-              domain, account,
-              stack : stack._id
-              group : group.slug
-            }, (err, r)->
-              console.warn err  if err?
-              results.domains.push { err, obj: r }
-              queue.next()
-
-        template.connections?.forEach (c)->
-
-          queue.push ->
-
-            # Assign rule to domain
-            if c.rules? and c.domains?
-
-              rule   = results.rules[c.rules]
-              domain = results.domains[c.domains]
-
-              if not rule?.err and not domain?.err
-                results.connections.push
-                  err : new KodingError "Not implemented"
-                  obj : null
-              else
-                results.connections.push
-                  err : new KodingError "Missing edge"
-                  obj : null
-
-              queue.next()
-
-            # Assign a domain to machine
-            else if c.machines? and c.domains?
-
-              domain  = results.domains[c.domains]
-              machine = results.machines[c.machines]
-
-              if not domain?.err and not machine?.err
-
-                domain.obj.bindMachine machine.obj.getId(), (err)->
-                  results.connections.push { err, obj: ok: !err? }
-                  queue.next()
-
-              else
-                results.connections.push
-                  err : new KodingError "Missing edge"
-                  obj : null
-                queue.next()
-
-            else
-              queue.next()
-
-        queue.push ->
-
-          callback null, {stack, results}
-
-        daisy queue
+        account.addStackTemplate template, (err) ->
+          return callback err  if err
+
+          ComputeProvider.generateStackFromTemplate res, options, callback
 
 
   do ->
 
     JGroup = require '../group'
-    JGroup.on 'MemberAdded', ({group, member})->
+    JGroup.on 'MemberAdded', ({group, member}) ->
 
       # No need to try creating group stacks for guests or koding group members
       return  if group.slug in ['guests', 'koding']


      ComputeProvider.createGroupStack client,
        addGroupAdminToMachines: yes
      , (err, res = {})->

        {stack, results} = res


          (signature Function)
        createGroupStack  :
          (signature Function)
        createStackFromTemplate :
          (signature Object, Function)


  @providers      = PROVIDERS
