# File lib/deltacloud/drivers/vsphere/vsphere_driver.rb, line 137
    def instances(credentials, opts=nil)
      cloud = new_client(credentials)
      inst_arr, machine_vms, pending_vms = [], [], []
      safely do
        # Using find_vm is a way faster than listing all virtual machines
        if opts[:id]
          list_vms = [ find_vm(credentials, opts[:id]) ].compact
        else
          list_vms = list_virtual_machines(credentials)
        end
        # Split machines to the 'real' one and PENDING one.
        machine_vms = list_vms.select { |vm| vm[:instance] && !vm[:instance].summary.config[:template] }
        pending_vms = list_vms.select { |vm| vm[:stored_instance] }.collect { |vm| vm[:stored_instance]}
      end
      safely do
        inst_arr = machine_vms.collect do |vm_hash|
          # Since all calls to vm are threaten as SOAP calls, reduce them using
          # local variable.
          vm, realm_id = vm_hash[:instance], vm_hash[:datastore]
          config = vm.summary.config
          next if not config
          # Template (image_id) is beeing stored as 'extraConfig' parameter in
          # instance.
          template_id = vm.config[:extraConfig].select { |k| k.key == 'template_id' }
          template_id = template_id.first.value unless template_id.empty?
          properties = {
            :memory => config[:memorySizeMB],
            :cpus => config[:numCpu],
            :storage => vm.summary.storage[:unshared],
            :name => config[:name],
            :full_name => config[:guestFullName],
          }
          instance_state = convert_state(:instance, vm.summary.runtime[:powerState])
          instance_profile = InstanceProfile::new('default',
                                                  :hwp_cpu => properties[:cpus],
                                                  :hwp_memory => properties[:memory],
                                                  :hwp_storage => properties[:storage])
          # We're getting IP address from 'vmware guest tools'.
          # If guest tools are not installed, we return list of MAC addresses
          # assigned to this instance.
          instance_address = vm.guest[:net].empty? ? vm.macs.values.first : vm.guest[:net].first[:ipAddress].first
          Instance.new(
            :id => properties[:name],
            :name => properties[:name],
            :owner_id => credentials.user,
            :image_id => template_id,
            :description => properties[:full_name],
            :realm_id => realm_id,
            :state => instance_state,
            :public_addresses => instance_address,
            :private_addresses => [],
            :instance_profile => instance_profile,
            :actions => instance_actions_for( instance_state ),
            :create_image => true
          )
        end
      end
      inst_arr.compact!
      # Append 'temporary' instances to real instances.
      # 'Temporary' or 'stored' instance are used to speed up instance creation
      # process by serializing instances to datastore and map instance to task.
      #
      inst_arr += pending_vms
      filter_on( inst_arr, :state, opts )
    end