def list_nodes(self, project=None, location=None):
        """
        @inherits: :class:`NodeDriver.list_nodes`

        :keyword    project: Limit nodes returned to those configured under
                             the defined project.
        :type       project: :class:`.CloudStackProject`

        :keyword    location: Limit nodes returned to those in the defined
                              location.
        :type       location: :class:`.NodeLocation`

        :rtype: ``list`` of :class:`CloudStackNode`
        """

        args = {}

        if project:
            args['projectid'] = project.id

        if location is not None:
            args['zoneid'] = location.id

        vms = self._sync_request('listVirtualMachines', params=args)
        addrs = self._sync_request('listPublicIpAddresses', params=args)
        port_forwarding_rules = self._sync_request('listPortForwardingRules')
        ip_forwarding_rules = self._sync_request('listIpForwardingRules')

        public_ips_map = {}
        for addr in addrs.get('publicipaddress', []):
            if 'virtualmachineid' not in addr:
                continue
            vm_id = str(addr['virtualmachineid'])
            if vm_id not in public_ips_map:
                public_ips_map[vm_id] = {}
            public_ips_map[vm_id][addr['ipaddress']] = addr['id']

        nodes = []

        for vm in vms.get('virtualmachine', []):
            public_ips = public_ips_map.get(str(vm['id']), {}).keys()
            public_ips = list(public_ips)
            node = self._to_node(data=vm, public_ips=public_ips)

            addresses = public_ips_map.get(str(vm['id']), {}).items()
            addresses = [CloudStackAddress(id=address_id, address=address,
                                           driver=node.driver) for
                         address, address_id in addresses]
            node.extra['ip_addresses'] = addresses

            rules = []
            for addr in addresses:
                for r in ip_forwarding_rules.get('ipforwardingrule', []):
                    if str(r['virtualmachineid']) == node.id:
                        rule = CloudStackIPForwardingRule(node, r['id'],
                                                          addr,
                                                          r['protocol']
                                                          .upper(),
                                                          r['startport'],
                                                          r['endport'])
                        rules.append(rule)
            node.extra['ip_forwarding_rules'] = rules

            rules = []
            for r in port_forwarding_rules.get('portforwardingrule', []):
                if str(r['virtualmachineid']) == node.id:
                    addr = [CloudStackAddress(id=a['id'],
                                              address=a['ipaddress'],
                                              driver=node.driver)
                            for a in addrs.get('publicipaddress', [])
                            if a['ipaddress'] == r['ipaddress']]
                    rule = CloudStackPortForwardingRule(node, r['id'],
                                                        addr[0],
                                                        r['protocol'].upper(),
                                                        r['publicport'],
                                                        r['privateport'],
                                                        r['publicendport'],
                                                        r['privateendport'])
                    if not addr[0].address in node.public_ips:
                        node.public_ips.append(addr[0].address)
                    rules.append(rule)
            node.extra['port_forwarding_rules'] = rules

            nodes.append(node)

        return nodes
dataset/ETHPy150Open apache/libcloud/libcloud/compute/drivers/cloudstack.py/CloudStackNodeDriver.list_nodes/original