feat: initial version
diff --git a/README.md b/README.md
index 3762217..720079c 100644
--- a/README.md
+++ b/README.md
@@ -3,8 +3,12 @@
 
 This plugin provides Gradle ability to generate SSH keys.
 
-Usage:
+It uses [JSch](http://www.jcraft.com/jsch/) Java library,
+no installation of extra tools is required.
+
+## Usage
 ```
+
 plugins {
   id 'org.fidata.keygen'
 }
@@ -26,12 +30,18 @@
 `keyType` and `keySize` properties can be set per-task via its properties.
 Otherwise, project-wide values from `keygen` extension are used.
 
-
-
-
+Since keys can't be restored, to prevent key loss task will run
+**only if either private or public key file doesn't exist**.
+If you want to regenerate key (including when you changed desired key
+properties) you should clean them manually beforehand.
 
 Other types of keys could be supported in the future.
 
+### Compatibility
+
+*   Gradle >= 4.4
+*   Developed and tested with JDK 8
+
 
 ------------------------------------------------------------------------
 Copyright © 2018  Basil Peace
diff --git a/build.gradle b/build.gradle
index 63cb9c5..b8b08dd 100644
--- a/build.gradle
+++ b/build.gradle
@@ -62,7 +62,7 @@
   }
 }
 
-tasks.codenarcCompatTest.disabledRules.add 'JavaIoPackageAccess'
+tasks.codenarcCompatTest.disabledRules.addAll 'JavaIoPackageAccess', 'DuplicateNumberLiteral'
 
 pluginBundle.plugins {
   keygenPlugin {
diff --git a/src/compatTest/groovy/org/fidata/gradle/KeygenPluginSpecification.groovy b/src/compatTest/groovy/org/fidata/gradle/KeygenPluginSpecification.groovy
index d1e2af1..ae83e32 100644
--- a/src/compatTest/groovy/org/fidata/gradle/KeygenPluginSpecification.groovy
+++ b/src/compatTest/groovy/org/fidata/gradle/KeygenPluginSpecification.groovy
@@ -19,12 +19,13 @@
  */
 package org.fidata.gradle
 
-import com.jcraft.jsch.KeyPairRSA
 import spock.lang.Specification
 import org.gradle.testkit.runner.GradleRunner
 import org.gradle.testkit.runner.BuildResult
 import com.jcraft.jsch.JSch
 import com.jcraft.jsch.KeyPair
+import com.jcraft.jsch.KeyPairRSA
+import com.jcraft.jsch.KeyPairDSA
 import java.nio.file.Files
 import org.apache.commons.io.FileUtils
 
@@ -36,10 +37,11 @@
   boolean success = false
 
   final File testProjectDir = Files.createTempDirectory('compatTest').toFile()
+  final File testProjectDir2 = File.createTempDir('compatTest', null)
+
+  final File buildDir = new File(testProjectDir, 'build')
 
   File buildFile = new File(testProjectDir, 'build.gradle')
-  File settingsFile = new File(testProjectDir, 'settings.gradle')
-  File propertiesFile = new File(testProjectDir, 'gradle.properties')
 
   // fixture methods
 
@@ -72,12 +74,12 @@
   // void cleanupSpec() { }
 
   // feature methods
-  void 'generates ssh key by default'() {
-    given: 'project build file'
+  void 'generates ssh key with project-wide settings'() {
+    given: 'build file'
     buildFile << '''\
       keygen {
         keyType = RSA
-        keySize = 4096
+        keySize = 2048
       }
 
       task('generateSSHKey', type: GenerateSSHKeyTask) {
@@ -90,11 +92,11 @@
     build('generateSSHKey')
 
     then: 'private key file is generated'
-    File privateKeyFile = new File(testProjectDir, 'build/ssh_key')
+    File privateKeyFile = new File(buildDir, 'ssh_key')
     privateKeyFile.exists()
 
     and: 'public key file is generated'
-    File publicKeyFile = new File(testProjectDir, 'build/ssh_key.pub')
+    File publicKeyFile = new File(buildDir, 'ssh_key.pub')
     publicKeyFile.exists()
 
     when: 'generated key is loaded'
@@ -104,11 +106,11 @@
     then: 'no exception is thrown'
     noExceptionThrown()
 
-    and: 'key type is RSA'
+    and: 'key type equals to requested'
     kpair.keyType == KeyPair.RSA
 
-    and: 'key length is 4096'
-    ((KeyPairRSA)kpair).keySize == 4096
+    and: 'key length equals to requested'
+    ((KeyPairRSA)kpair).keySize == 2048
 
     and: 'public key comment is set'
     kpair.publicKeyComment == 'test@example.com'
@@ -116,6 +118,69 @@
     (success = true) != null
   }
 
+  // feature methods
+  void 'generates ssh key with per-task settings'() {
+    given: 'build file'
+    buildFile << '''\
+      keygen {
+        keyType = RSA
+        keySize = 4096
+      }
+
+      task('generateSSHKey', type: GenerateSSHKeyTask) {
+        privateKeyFile = new File(buildDir, 'ssh_key')
+        keyType = DSA
+        keySize = 2048
+        email = 'test@example.com'
+      }
+    '''.stripIndent()
+
+    when: 'generateSSHKey task is run'
+    build('generateSSHKey')
+
+    then: 'key type equals to requested'
+    File privateKeyFile = new File(buildDir, 'ssh_key')
+    File publicKeyFile = new File(buildDir, 'ssh_key.pub')
+    JSch jSch = new JSch()
+    KeyPair kpair = KeyPair.load(jSch, privateKeyFile.bytes, publicKeyFile.bytes)
+    kpair.keyType == KeyPair.DSA
+
+    and: 'key length equals to requested'
+    ((KeyPairDSA)kpair).keySize == 2048
+
+    (success = true) != null
+  }
+
+  // feature methods
+  void 'don\'t override existing key files'() {
+    given: 'build file'
+    buildFile << '''\
+      task('generateSSHKey', type: GenerateSSHKeyTask) {
+        privateKeyFile = new File(buildDir, 'ssh_key')
+        email = 'test@example.com'
+      }
+    '''.stripIndent()
+
+    and: 'private key file exists'
+    buildDir.mkdir()
+    String dummyKey = 'Dummy key'
+    File privateKeyFile = new File(buildDir, 'ssh_key')
+    privateKeyFile.text = dummyKey
+    File publicKeyFile = new File(buildDir, 'ssh_key.pub')
+    publicKeyFile.text = dummyKey
+
+    when: 'generateSSHKey task is run'
+    build('generateSSHKey')
+
+    then: 'private key file is not overriden'
+    privateKeyFile.text == dummyKey
+
+    and: 'public key file is not overriden'
+    publicKeyFile.text == dummyKey
+
+    (success = true) != null
+  }
+
   // helper methods
   protected BuildResult build(String... arguments) {
     GradleRunner.create()
diff --git a/src/main/groovy/org/fidata/gradle/tasks/GenerateSSHKeyTask.groovy b/src/main/groovy/org/fidata/gradle/tasks/GenerateSSHKeyTask.groovy
index 3cf714a..20a6f92 100644
--- a/src/main/groovy/org/fidata/gradle/tasks/GenerateSSHKeyTask.groovy
+++ b/src/main/groovy/org/fidata/gradle/tasks/GenerateSSHKeyTask.groovy
@@ -59,13 +59,13 @@
    */
   @Optional
   @Input
-  final Property<Integer> keyType
+  final Property<Integer> keyType = project.objects.property(Integer)
   /**
    * Size of the key
    */
   @Optional
   @Input
-  final Property<Integer> keySize
+  final Property<Integer> keySize = project.objects.property(Integer)
   /**
    * Email to add to public key as comment
    */
@@ -73,9 +73,13 @@
   String email
 
   GenerateSSHKeyTask() {
-    keyType = project.objects.property(Integer)
+    /*
+     * WORKAROUND:
+     * We have to reset standard type value to null manually
+     * https://github.com/gradle/gradle/issues/6108
+     * <grv87 2018-07-27>
+     */
     keyType.set((Integer)null)
-    keySize = project.objects.property(Integer)
     keySize.set((Integer)null)
     onlyIf {
       !privateKeyFile.get().asFile.exists() || !publicKeyFile.get().asFile.exists()