# File lib/openshift-origin-msg-broker-mcollective/lib/openshift/mcollective_application_container_proxy.rb, line 738
      def move_gear(app, gear, destination_container, destination_district_uuid, allow_change_district, node_profile)
        reply = ResultIO.new
        state_map = {}
        gear.node_profile = node_profile if node_profile
        orig_uid = gear.uid

        # resolve destination_container according to district
        destination_container, destination_district_uuid, keep_uid = resolve_destination(app, gear, destination_container, destination_district_uuid, allow_change_district)

        source_container = gear.container
        destination_node_profile = destination_container.get_node_profile
        if app.scalable and source_container.get_node_profile != destination_node_profile
          log_debug "Cannot change node_profile for a gear belonging to a scalable application. The destination container's node profile is #{destination_node_profile}, while the gear's node_profile is #{gear.node_profile}"
          raise OpenShift::UserException.new("Error moving app.  Cannot change node profile.", 1)
        end

        # get the state of all cartridges
        quota_blocks = nil
        quota_files = nil
        idle, leave_stopped, quota_blocks, quota_files = get_app_status(app)
        gi = app.group_instance_map[gear.group_instance_name]
        gi.component_instances.each do |ci_name|
          cinst = app.comp_instance_map[ci_name]
          cart = cinst.parent_cart_name
          next if cart == app.name
          # idle, leave_stopped, quota_blocks, quota_files = get_cart_status(app, gear, cart)
          state_map[ci_name] = [idle, leave_stopped]
        end

        begin
          # pre-move
          reply.append move_gear_pre(app, gear, state_map, keep_uid)

          begin
            # rsync gear with destination container
            rsync_destination_container(app, gear, destination_container, destination_district_uuid, quota_blocks, quota_files, keep_uid)

            # now execute 'move'/'expose-port' hooks on the new nest of the components
            app.configure_order.each do |ci_name|
              next if not gi.component_instances.include? ci_name
              cinst = app.comp_instance_map[ci_name]
              cart = cinst.parent_cart_name
              next if cart == app.name
              idle, leave_stopped = state_map[ci_name]
              if embedded_carts.include? cart 
                if app.scalable and cart.include? app.proxy_cartridge
                  log_debug "DEBUG: Performing cartridge level move for '#{cart}' on #{destination_container.id}"
                  reply.append destination_container.send(:run_cartridge_command, cart, app, gear, "move", idle ? '--idle' : nil, false)
                else
                  log_debug "DEBUG: Performing cartridge level move for embedded #{cart} for '#{app.name}' on #{destination_container.id}"
                  embedded_reply = destination_container.send(:run_cartridge_command, "embedded/" + cart, app, gear, "move", nil, false)
                  component_details = embedded_reply.appInfoIO.string
                  unless component_details.empty?
                    app.set_embedded_cart_info(cart, component_details)
                  end
                  reply.append embedded_reply
                  unless keep_uid
                    log_debug "DEBUG: Performing cartridge level post-move for embedded #{cart} for '#{app.name}' on #{destination_container.id}"
                    reply.append destination_container.send(:run_cartridge_command, "embedded/" + cart, app, gear, "post-move", nil, false)
                  end
                end
              end
              if framework_carts.include? cart
                log_debug "DEBUG: Performing cartridge level move for '#{cart}' on #{destination_container.id}"
                reply.append destination_container.send(:run_cartridge_command, cart, app, gear, "move", idle ? '--idle' : nil, false)
              end
              if app.scalable and not cart.include? app.proxy_cartridge
                begin
                  reply.append destination_container.expose_port(app, gear, cinst.parent_cart_name)
                rescue Exception=>e
                  # just pass because some embedded cartridges do not have expose-port hook implemented (e.g. jenkins-client)
                end
              end
            end 

            # start the gears again and change DNS entry
            reply.append move_gear_post(app, gear, destination_container, state_map)
            app.elaborate_descriptor
            app.execute_connections
            if app.scalable
              # execute connections restart the haproxy service, so stop it explicitly if needed
              app.start_order.reverse.each do |ci_name|
                next if not gi.component_instances.include? ci_name
                cinst = app.comp_instance_map[ci_name]
                cart = cinst.parent_cart_name
                next if cart==app.name
                idle, leave_stopped = state_map[ci_name]
                if leave_stopped and cart.include? app.proxy_cartridge
                  log_debug "DEBUG: Explicitly stopping cartridge '#{cart}' in '#{app.name}' after move on #{destination_container.id}"
                  reply.append destination_container.stop(app, gear, cart)
                end
              end
            end
            if gear.node_profile != destination_node_profile
              log_debug "DEBUG: The gear's node profile changed from #{gear.node_profile} to #{destination_node_profile}"
              gear.node_profile = destination_node_profile
              if not app.scalable
                app.node_profile = destination_node_profile 
                gi.node_profile = destination_node_profile
              end
            end
            app.save

          rescue Exception =>e
            gear.container = source_container
            # remove-httpd-proxy of destination
            log_debug "DEBUG: Moving failed.  Rolling back gear '#{gear.name}' '#{app.name}' with remove-httpd-proxy on '#{destination_container.id}'"
            gi.component_instances.each do |ci_name|
              cinst = app.comp_instance_map[ci_name]
              cart = cinst.parent_cart_name
              next if cart == app.name
              if framework_carts.include? cart
                begin
                  reply.append destination_container.send(:run_cartridge_command, cart, app, gear, "remove-httpd-proxy", nil, false)
                rescue Exception => e
                  log_debug "DEBUG: Remove httpd proxy with cart '#{cart}' failed on '#{destination_container.id}'  - gear: '#{gear.name}', app: '#{app.name}'"
                end
              end
            end
            # destroy destination
            log_debug "DEBUG: Moving failed.  Rolling back gear '#{gear.name}' in '#{app.name}' with destroy on '#{destination_container.id}'"
            reply.append destination_container.destroy(app, gear, keep_uid, nil, true)
            raise
          end
        rescue Exception => e
          begin
            unless keep_uid
              # post_move source
              gi.component_instances.each do |ci_name|
                cinst = app.comp_instance_map[ci_name]
                cart = cinst.parent_cart_name
                next if cart==app.name
                proxy_cart = (app.proxy_cartridge or "")
                if embedded_carts.include? cart and not cart.include? proxy_cart
                  begin
                    log_debug "DEBUG: Performing cartridge level post-move for embedded #{cart} for '#{app.name}' on #{source_container.id}"
                    reply.append source_container.send(:run_cartridge_command, "embedded/" + cart, app, gear, "post-move", nil, false)
                  rescue Exception => e
                    log_error "ERROR: Error performing cartridge level post-move for embedded #{cart} for '#{app.name}' on #{source_container.id}: #{e.message}"
                  end
                end
              end
            end
            # start source
            gi.component_instances.each do |ci_name|
              cinst = app.comp_instance_map[ci_name]
              cart = cinst.parent_cart_name
              next if cart==app.name
              idle, leave_stopped = state_map[ci_name]
              if not leave_stopped
                reply.append source_container.run_cartridge_command(cart, app, gear, "start", nil, false) if framework_carts.include? cart
              end
            end
          ensure
            raise
          end
        end

        move_gear_destroy_old(app, gear, keep_uid, orig_uid, source_container, destination_container)

        log_debug "Successfully moved '#{app.name}' with gear uuid '#{gear.uuid}' from '#{source_container.id}' to '#{destination_container.id}'"
        reply
      end