Added credentials and nodes existence testing.
diff --git a/README.rst b/README.rst
index 896a95b..319e0b7 100644
--- a/README.rst
+++ b/README.rst
@@ -349,7 +349,9 @@
               num_executors: 1
               node_mode: Normal
               ret_strategy: Always
-              label: example_label
+              labels:
+                - example
+                - label
               launcher:
                  type: jnlp
 
@@ -366,7 +368,9 @@
               num_executors: 1
               node_mode: Normal
               ret_strategy: Always
-              label: example_label
+              labels:
+                - example
+                - label 
               launcher:
                  type: ssh
                  host: test-launcher
diff --git a/_states/jenkins_credential.py b/_states/jenkins_credential.py
index f2d4b03..ce44fe6 100644
--- a/_states/jenkins_credential.py
+++ b/_states/jenkins_credential.py
@@ -10,42 +10,36 @@
 import com.cloudbees.plugins.credentials.domains.Domain;
 import com.cloudbees.plugins.credentials.CredentialsScope;
 
-domain = Domain.global()
-store = Jenkins.instance.getExtensionList(
-  'com.cloudbees.plugins.credentials.SystemCredentialsProvider'
-)[0].getStore()
+def creds = com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials(
+        com.cloudbees.plugins.credentials.common.StandardUsernameCredentials.class,
+        Jenkins.instance
+    )
 
-credentials_new = new {clazz}(
-  {params}
-)
+def result = creds.find{{ it.username == "{username}" && it.password.toString() == "{password}" }}
+if(result){{
+    print("EXISTS")
+}}else{{
+    domain = Domain.global()
+    store = Jenkins.instance.getExtensionList(
+      'com.cloudbees.plugins.credentials.SystemCredentialsProvider'
+    )[0].getStore()
 
-creds = com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials(
-      {clazz}.class, Jenkins.instance
-);
-updated = false;
+    credentials_new = new {clazz}(
+      {params}
+    )
 
-for (credentials_current in creds) {{
-  // Comparison does not compare passwords but identity.
-  if (credentials_new == credentials_current) {{
-    store.removeCredentials(domain, credentials_current);
+    creds = com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials(
+          {clazz}.class, Jenkins.instance
+    );
     ret = store.addCredentials(domain, credentials_new)
-    updated = true;
-    println("OVERWRITTEN");
-    break;
-  }}
-}}
-
-if (!updated) {{
-  ret = store.addCredentials(domain, credentials_new)
-  if (ret) {{
-    println("CREATED");
-  }} else {{
-    println("FAILED");
-  }}
+    if (ret) {{
+      print("CREATED");
+    }} else {{
+        print("FAILED");
+    }}
 }}
 """  # noqa
 
-
 def present(name, scope, username, password=None, desc="", key=None):
     """
     Main jenkins credentials state method
@@ -69,25 +63,30 @@
     if test:
         status = 'CREATED'
         ret['changes'][name] = status
-        ret['comment'] = 'Credentials ' + status.lower()
+        ret['comment'] = 'Credentials %s %s' % (name, status.lower())
     else:
         clazz = ""
         if key:
             clazz = "com.cloudbees.jenkins.plugins.sshcredentials.impl.BasicSSHUserPrivateKey"
-            params = 'CredentialsScope.{}, "{}", "{}", "{}"'.format(scope, name, desc, key)
+            params = 'CredentialsScope.{}, "{}", "{}", "{}"'.format(
+                scope, name, desc, key)
         else:
             clazz = "com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl"
-            params = 'CredentialsScope.{}, "{}", "{}", "{}", "{}"'.format(scope, name, desc, username, password)
+            params = 'CredentialsScope.{}, "{}", "{}", "{}", "{}"'.format(
+                scope, name, desc, username, password)
 
-        call_result = __salt__['jenkins_common.call_groovy_script'](create_credential_groovy, {"clazz": clazz, "params":params})
-        if call_result["code"] == 200 and call_result["msg"].strip() in ["CREATED", "OVERWRITTEN"]:
+        call_result = __salt__['jenkins_common.call_groovy_script'](
+            create_credential_groovy, {"username": username, "password": password, "clazz": clazz, "params": params})
+        if call_result["code"] == 200 and call_result["msg"] in ["CREATED", "EXISTS"]:
             status = call_result["msg"]
-            ret['changes'][name] = status
-            ret['comment'] = 'Credentials ' + status.lower()
+            if call_result["msg"] == "CREATED":
+                ret['changes'][name] = status
+            ret['comment'] = 'Credentials %s %s' % (name, status.lower())
             result = True
         else:
             status = 'FAILED'
-            logger.error("Jenkins credentials API call failure: %s", call_result["msg"])
+            logger.error(
+                "Jenkins credentials API call failure: %s", call_result["msg"])
             ret['comment'] = 'Jenkins credentials API call failure: %s' % (call_result["msg"])
     ret['result'] = None if test else result
     return ret
diff --git a/_states/jenkins_node.py b/_states/jenkins_node.py
index b80fd4d..388c9fb 100644
--- a/_states/jenkins_node.py
+++ b/_states/jenkins_node.py
@@ -7,9 +7,19 @@
 import hudson.model.*
 import hudson.slaves.*
 import hudson.plugins.sshslaves.*
-import java.util.ArrayList;
-import hudson.slaves.EnvironmentVariablesNodeProperty.Entry;
 
+def result=Jenkins.instance.slaves.find{{
+ it.name == '{name}' && 
+ it.numExecutors == {num_executors} &&
+ it.nodeDescription == "{desc}" && 
+ it.remoteFS == "{remote_home}" && 
+ it.labelString == "{label}" && 
+ it.mode == Node.Mode.{node_mode} && 
+ it.launcher.getClass().getName().equals({launcher}.getClass().getName()) &&
+ it.retentionStrategy.getClass().getName().equals(new hudson.slaves.RetentionStrategy.{ret_strategy}().getClass().getName())}}
+if(result){{
+    print("EXISTS")
+}}else{{
   Slave slave = new DumbSlave(
                     "{name}",
                     "{desc}",
@@ -21,7 +31,8 @@
                     new RetentionStrategy.{ret_strategy}(),
                     new LinkedList())
   Jenkins.instance.addNode(slave)
-  print "{name}"
+  print("CREATED")
+}}
 """  # noqa
 
 create_lbl_groovy = u"""\
@@ -81,7 +92,7 @@
     return ret
 
 
-def present(name, remote_home, launcher, num_executors="1", node_mode="Normal", desc="", label="", ret_strategy="Always"):
+def present(name, remote_home, launcher, num_executors="1", node_mode="Normal", desc="", labels=[], ret_strategy="Always"):
     """
     Jenkins node state method
 
@@ -90,6 +101,8 @@
     :param launcher: launcher dict with type, name, port, username, password
     :param num_executors: number of node executurs (optional, default 1)
     :param node_mode: node mode (optional, default Normal)
+    :param desc: node description (optional)
+    :param labels: node labels list (optional)
     :param ret_strategy: node retention strategy from RetentionStrategy class
     :returns: salt-specified state dict
     """
@@ -106,27 +119,29 @@
         ret['changes'][name] = status
         ret['comment'] = 'Node %s %s' % (name, status.lower())
     else:
-        launcher_string = "new JNLPLauncher()"
+        label_string = " ".join(labels)
+        launcher_string = "new hudson.slaves.JNLPLauncher()"
         if launcher:
             if launcher["type"] == "ssh":
-                launcher_string = 'new SSHLauncher("{}",{},"{}","{}","","","","","")'.format(
+                launcher_string = 'new hudson.plugins.sshslaves.SSHLauncher("{}",{},"{}","{}","","","","","")'.format(
                     launcher["host"], launcher["port"], launcher["username"], launcher["password"])
             elif launcher["type"] == "jnlp":
-                launcher_string = "new JNLPLauncher()"
+                launcher_string = "new hudson.slaves.JNLPLauncher()"
 
         call_result = __salt__['jenkins_common.call_groovy_script'](
             create_node_groovy,
             {"name": name,
                 "desc": desc,
-                "label": label,
+                "label": label_string,
                 "remote_home": remote_home,
                 "num_executors": num_executors,
                 "launcher": launcher_string,
                 "node_mode": node_mode.upper(),
                 "ret_strategy": ret_strategy})
-        if call_result["code"] == 200 and call_result["msg"].strip() == name:
-            status = "CREATED"
-            ret['changes'][name] = status
+        if call_result["code"] == 200 and call_result["msg"] in ["CREATED", "EXISTS"]:
+            status = call_result["msg"]
+            if call_result["msg"] == "CREATED":
+                ret['changes'][name] = status
             ret['comment'] = 'Node %s %s' % (name, status.lower())
             result = True
         else:
diff --git a/jenkins/client/node.sls b/jenkins/client/node.sls
index d618a2f..8412137 100644
--- a/jenkins/client/node.sls
+++ b/jenkins/client/node.sls
@@ -9,7 +9,7 @@
     - num_executors: {{ node.get('num_executors','1') }}
     - node_mode: {{ node.get('node_mode','Normal') }}
     - ret_strategy: {{ node.get('ret_strategy','Always') }}
-    - label: {{ node.get('label','') }}
+    - labels: {{ node.get('labels',[]) }}
 {% endfor %}
 
 {% for node_name, label in client.get("label",{}).iteritems() %}