').addClass('loading-overlay');
    var $actions = args.$actions;
    var actionArgs = args.action.action;
    var action = actionArgs.action;
    var actionID = args.action.id;
    var notification = actionArgs.notification;
    var label = actionArgs.label;
    var context = args.context;
    var actionPreFilter = args.actionPreFilter;
    var success = function(args) {
      var remove = args ? args.remove : false;
      var _custom = args ? args._custom : {};
      cloudStack.ui.notifications.add(
        // Notification
        {
          desc: label,
          poll: notification.poll,
          _custom: _custom
        },
        // Success
        function(args) {
          var newData = args.data ? args.data : {};
          var newTier = $.extend(true, {}, context.tiers[0], newData);
          var newContext = $.extend(true, {}, context);
          // Update data
          newContext.tiers = [newTier];
          if (remove) {
            $tier.remove();
          } else {
            $loading.remove();
          }
          if (actionID == 'addVM') {
            // Increment VM total
            var $total = $tier.find('.vm-count .total');
            var prevTotal = parseInt($total.html());
            var newTotal = prevTotal + 1;
            $total.html(newTotal);
          }
          filterActions({
            $actions: $actions,
            actionPreFilter: actionPreFilter,
            context: newContext
          });
        },
        {},
        // Error
        function(args) {
          $loading.remove();
        }
      );
    };
    switch(actionID) {
      case 'addVM':
        action({
          context: context,
          complete: function(args) {
            $loading.appendTo($tier);
            success(args);
          }
        });
        break;
      case 'remove':
        $loading.appendTo($tier);
        action({
          context: context,
          response: {
            success: function(args) {
              success({ remove: true });
            }
          }
        });
        break;
      case 'acl':
      // Show ACL dialog
      $('
').multiEdit(
        $.extend(true, {}, actionArgs.multiEdit, {
          context: context
        })
      ).dialog({
        title: 'Configure ACL',
        dialogClass: 'configure-acl',
        width: 820,
        height: 600,
        buttons: {
          'Done': function() {
            $(':ui-dialog').remove();
            $('.overlay').remove();
          }
        }
      }).closest('.ui-dialog').overlay();
      break;
      default:
        $loading.appendTo($tier);
        action({
          context: context,
          complete: success,
          response: {
            success: success,
            error: function(args) { $loading.remove(); }
          }
        });
    }
  };
  // Appends a new tier to chart
  var addNewTier = function(args) {
    var actions = args.actions;
    var vmListView = args.vmListView;
    var actionPreFilter = args.actionPreFilter;
    var context = args.context;
    var tier = $.extend(args.tier, {
      context: context,
      vmListView: vmListView,
      actions: actions,
      actionPreFilter: actionPreFilter,
      virtualMachines: []
    });
    var $tiers = args.$tiers;
    $tiers.find('li.placeholder')
      .before(
        elems.tier(tier)
          .hide()
          .fadeIn('slow')
      );
  };
  // Renders the add tier form, in a dialog
  var addTierDialog = function(args) {
    var actions = args.actions;
    var context = args.context;
    var vmListView = args.vmListView;
    var actionPreFilter = args.actionPreFilter;
    var $tiers = args.$tiers;
    cloudStack.dialog.createForm({
      form: actions.add.createForm,
      after: function(args) {
        var $loading = $('
').addClass('loading-overlay').prependTo($tiers.find('li.placeholder'));
        actions.add.action({
          context: context,
          data: args.data,
          response: {
            success: function(args) {
              var tier = args.data;
              cloudStack.ui.notifications.add(
                // Notification
                {
                  desc: actions.add.label,
                  poll: actions.add.notification.poll
                },
                // Success
                function(args) {
                  $loading.remove();
                  addNewTier({
                    context: $.extend(true, {}, context, {
                      tiers: [tier]
                    }),
                    tier: tier,
                    $tiers: $tiers,
                    actions: actions,
                    actionPreFilter: actionPreFilter,
                    vmListView: vmListView
                  });
                },
                {},
                // Error
                function(args) {
                  $loading.remove();
                }
              );
            }
          }
        });
      }
    });
  };
  cloudStack.uiCustom.vpc = function(args) {
    var vmListView = args.vmListView;
    var tierArgs = args.tiers;
    var siteToSiteVPN = args.siteToSiteVPN;
    return function(args) {
      var context = args.context;
      var $browser = $('#browser .container');
      var $toolbar = $('
').addClass('toolbar');
      var vpc = args.context.vpc[0];
      $browser.cloudBrowser('addPanel', {
        maximizeIfSelected: true,
        title: 'Configure VPC: ' + vpc.name,
        complete: function($panel) {
          var $loading = $('
').addClass('loading-overlay').appendTo($panel);
          $panel.append($toolbar);
          // Load data
          tierArgs.dataProvider({
            context: context,
            response: {
              success: function(args) {
                var tiers = args.data.tiers;
                var $chart = elems.chart({
                  $browser: $browser,
                  siteToSiteVPN: siteToSiteVPN,
                  vmListView: vmListView,
                  context: context,
                  actions: tierArgs.actions,
                  actionPreFilter: tierArgs.actionPreFilter,
                  vpcName: vpc.name,
                  tiers: tiers
                }).appendTo($panel);
                $loading.remove();
                $chart.fadeIn(function() {
                });
              }
            }
          });
        }
      });
    };
  };
}(jQuery, cloudStack));