diff --git a/src/execo_g5k/planning.py b/src/execo_g5k/planning.py
index 7d2fa2dc7beffbc5f96c6f0a255bb8a624e2d697..5765e68f535882155e4cf36870fc1a1df7064c0c 100644
--- a/src/execo_g5k/planning.py
+++ b/src/execo_g5k/planning.py
@@ -30,7 +30,7 @@ from execo_g5k import OarSubmission, get_current_oar_jobs, get_oar_job_info, \
 from execo_g5k.api_utils import get_g5k_sites, get_g5k_clusters, \
     get_cluster_site, get_site_clusters, get_resource_attributes, get_host_cluster, \
     get_host_site, get_host_attributes, get_g5k_hosts, get_host_shortname, \
-    get_host_longname
+    get_host_longname, get_site_hosts
 from execo_g5k.config import g5k_configuration
 from execo_g5k.utils import G5kAutoPortForwarder
 from itertools import cycle
@@ -114,7 +114,7 @@ def get_planning(elements=['grid5000'], vlan=False, subnet=False, storage=False,
         sites = elements = get_g5k_sites()
     else:
         sites = list(set([site for site in elements
-                          if site in get_g5k_sites()] + 
+                          if site in get_g5k_sites()] +
                          [get_cluster_site(cluster) for cluster in elements
                           if cluster in get_g5k_clusters(queues=queues)] +
                          [get_host_site(host) for host in elements
@@ -280,7 +280,7 @@ def max_resources(planning):
                 resources["grid5000"] += 1
                 resources[cl] += 1
                 resources[site] +=1
-    
+
     return resources
 
 def compute_coorm_slots(planning, excluded_elements=None):
@@ -500,98 +500,78 @@ def get_jobs_specs(resources, excluded_elements=None, name=None):
     jobs_specs = []
     if excluded_elements == None:
         excluded_elements = []
+    g5k_nodes = [ get_host_longname(h) for h in get_g5k_hosts(queues=None) ]
 
     # Creating the list of sites used
     sites = []
     real_resources = resources.copy()
     for resource in resources:
+        if resource in excluded_elements:
+            continue
         if resource in get_g5k_sites() and resource not in sites:
             sites.append(resource)
-        if resource in get_g5k_clusters(queues=None):
-            if resource not in excluded_elements:
-                site = get_cluster_site(resource)
-                if site not in sites:
-                    sites.append(site)
-                if site not in real_resources:
-                    real_resources[site] = 0
+        elif resource in get_g5k_clusters(queues=None):
+            site = get_cluster_site(resource)
+            if site not in sites:
+                sites.append(site)
+            if site not in real_resources:
+                real_resources[site] = 0
+        elif resource in g5k_nodes:
+            site = get_host_site(resource)
+            if site not in sites:
+                sites.append(site)
+            if site not in real_resources:
+                real_resources[site] = 0
 
     # Checking if we need a Kavlan, a KaVLAN global or none
-    get_kavlan = 'kavlan' in resources
-    if get_kavlan:
-        kavlan = 'kavlan'
-        n_sites = 0
-        for resource in real_resources:
-            if resource in sites:
-                n_sites += 1
-            if n_sites > 1:
-                kavlan += '-global'
-                break
-
-    blacklisted_hosts = {}
-    for element in excluded_elements:
-        if element not in get_g5k_clusters(queues=None) + get_g5k_sites():
-            site = get_host_site(element)
-            if not 'site' in blacklisted_hosts:
-                blacklisted_hosts[site] = [element]
-            else:
-                blacklisted_hosts[site].append(element)
+    get_kavlan = False
+    if 'kavlan' in resources:
+        get_kavlan = True
+        if len(sites) > 1:
+            kavlan = 'kavlan-global'
+        else:
+            kavlan = 'kavlan'
 
     for site in sites:
-        sub_resources = ''
-        # Adding a KaVLAN if needed
+        if site in excluded_elements:
+            continue
+        site_nodes = set([ get_host_longname(h) for h in get_site_hosts(site, queues=None) ])
+        rdefs = []
+
+        # hosts / clusters sql filters
+        excluded_hosts_constraints = []
+        excluded_clusters_constraints = []
+        site_excluded_hosts = site_nodes.intersection(excluded_elements)
+        if len(site_excluded_hosts) > 0:
+            excluded_hosts_constraints = [ 'host NOT IN (' + ', '.join([ "'" + h + "'" for h in site_excluded_hosts ]) + ')' ]
+        site_excluded_clusters = set(get_site_clusters(site, queues=None)).intersection(excluded_elements)
+        if len(site_excluded_clusters) > 0:
+            excluded_clusters_constraints = [ 'cluster NOT IN (' + ', '.join([ "'" + c + "'" for c in site_excluded_clusters ]) + ')' ]
+
+        # explicit hosts
+        site_explicit_hosts = site_nodes.intersection(resources).difference(excluded_elements)
+        site_explicit_hosts = set([ h for h in site_explicit_hosts if get_host_cluster(h) not in excluded_elements ])
+        if len(site_explicit_hosts) > 0:
+            rdefs.append('{host IN (' + ', '.join([ "'" + h + "'" for h in site_explicit_hosts ]) + ')}/nodes=' + str(len(site_explicit_hosts)))
+
+        # hosts in clusters
+        site_clusters = set(get_site_clusters(site, queues=None)).intersection(resources.keys()).difference(excluded_elements)
+        for cluster in site_clusters:
+            cluster_constraints = [ "cluster='" + cluster + "'" ]
+            rdefs.append('{' + ' AND '.join(cluster_constraints + excluded_hosts_constraints) + '}/nodes=' + str(resources[cluster]))
+
+        # hosts in site
+        if site in resources:
+            rdefs.append('{' + ' AND '.join(excluded_hosts_constraints + excluded_clusters_constraints) + '}/nodes=' + str(resources[site]))
+
+        # kavlan
         if get_kavlan:
-            if not 'global' in kavlan:
-                sub_resources = "{type='" + kavlan + "'}/vlan=1+"
-                get_kavlan = False
-            elif site in resources['kavlan']:
-                sub_resources = "{type='" + kavlan + "'}/vlan=1+"
+            if kavlan != 'kavlan-global' or site in resources['kavlan']:
+                rdefs.append("{type='" + kavlan + "'}/vlan=1+")
                 get_kavlan = False
 
-        base_sql = '{'
-        end_sql = '}/'
-
-        # Creating blacklist SQL string for hosts
-        host_blacklist = False
-        str_hosts = ''
-        if site in blacklisted_hosts and len(blacklisted_hosts[site]) > 0:
-            str_hosts = ''.join(["host not in ('" + get_host_longname(host) + "') and "
-                                for host in blacklisted_hosts[site]])
-            host_blacklist = True
-
-        #Adding the clusters blacklist
-        str_clusters = str_hosts if host_blacklist else ''
-        cl_blacklist = False
-        clusters_nodes = 0
-        for cluster in get_site_clusters(site, queues=None):
-            if cluster in resources and resources[cluster] > 0:
-                if str_hosts == '':
-                    sub_resources += "{cluster='" + cluster + "'}"
-                else:
-                    sub_resources += base_sql + str_hosts + "cluster='" + \
-                        cluster + "'" + end_sql
-                sub_resources += "/nodes=" + str(resources[cluster]) + '+'
-                clusters_nodes += resources[cluster]
-            if cluster in excluded_elements:
-                str_clusters += "cluster not in ('" + cluster + "') and "
-                cl_blacklist = True
-
-        # Generating the site blacklist string from host and cluster blacklist
-        str_site = ''
-        if host_blacklist or cl_blacklist:
-            str_site += base_sql
-            if not cl_blacklist:
-                str_site += str_hosts[:-4]
-            else:
-                str_site += str_clusters[:-4]
-            str_site = str_site + end_sql
-
-        if real_resources[site] > 0:
-            sub_resources += str_site + "nodes=" + str(real_resources[site]) +\
-                '+'
-
-        if sub_resources != '':
-            jobs_specs.append((OarSubmission(resources=sub_resources[:-1],
-                                             name=name), site))
+        if len(rdefs) > 0:
+            jobs_specs.append((OarSubmission(resources='+'.join(rdefs), name=name), site))
 
     return jobs_specs