diff --git a/.travis.yml b/.travis.yml
index f817fdcb0ee6b04cca367a4e0769f713dd433b00..aefe0aac694c28e49b6ea0bbe3908b50e0a480ed 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,26 +2,46 @@
 language: ruby
 # Workaround https://github.com/bundler/bundler/issues/3558
 before_install: gem install bundler
+install: bundle install --jobs 4 --retry 2 --without development
 script: bundle exec rake
 rvm:
   - 1.9.3
   - 2.1.6
+  - 2.2.6
+  - 2.3.3
+  - 2.4.0
 env:
-  - PUPPET_VERSION="~> 3.0.0"
-  - PUPPET_VERSION="~> 3.1.0"
-  - PUPPET_VERSION="~> 3.2.0"
-  - PUPPET_VERSION="~> 3.4.0"
-  - PUPPET_VERSION="~> 3.7.3"
-  - PUPPET_VERSION="~> 4.2.0"
-  - PUPPET_VERSION="~> 4.3.0"
+  - PUPPET_VERSION="~> 3.8.7"
+  - PUPPET_VERSION="~> 4.8.0"
+  - PUPPET_VERSION="~> 4.9.0"
   - PUPPET_VERSION=">= 0"
+  - PUPPET_VERSION="git://github.com/puppetlabs/puppet.git#master"
 matrix:
   exclude:
-    - rvm: 2.1.6
-      env: PUPPET_VERSION="~> 3.2.0"
-    - rvm: 2.1.6
-      env: PUPPET_VERSION="~> 3.1.0"
-    - rvm: 2.1.6
-      env: PUPPET_VERSION="~> 3.0.0"
+    - env: PUPPET_VERSION="~> 3.8.7"
+      rvm: 2.2.6
+    - env: PUPPET_VERSION="~> 3.8.7"
+      rvm: 2.3.3
+    - env: PUPPET_VERSION="~> 3.8.7"
+      rvm: 2.4.0
+    # 4.9 with Ruby 1.9.3 issues deprecation warnings
+    - env: PUPPET_VERSION="~> 4.9.0"
+      rvm: 1.9.3
+    - env: PUPPET_VERSION=">= 0"
+      rvm: 1.9.3
+    - env: PUPPET_VERSION="git://github.com/puppetlabs/puppet.git#master"
+      rvm: 1.9.3
   allow_failures:
     - env: PUPPET_VERSION=">= 0"
+    - env: PUPPET_VERSION="git://github.com/puppetlabs/puppet.git#master"
+deploy:
+  provider: rubygems
+  api_key:
+    secure: "kwxryZZ/t9EkWuYxhz3G1v+U3ZK4WdsiN0UFHDjijnAGPxqe/n+oBcNA8hOiNhjZeTFo8bADEZkL7JtdKQo9RvgStipyaS5gDHB/C1c4LOBWv4Tga21NNCAuBcE2CDtAH3+TzrZV5vv2+SpOrhKZpzZoAoR6PR1MWVWMUie/rE0="
+  gem: puppet-syntax
+  on:
+    rvm: 2.4.0
+    condition: '"$PUPPET_VERSION" = "~> 4.8.0"'
+    tags: true
+    all_branches: true
+    repo: voxpupuli/puppet-syntax
diff --git a/CHANGELOG b/CHANGELOG
index e243e8480043d6e4bff082d1b91b63f4412134f4..cfca27cd5be9b76a7c55b5ce6c8a88e51ced17f4 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,20 @@
+2017-06-29 Release 2.4.1
+- Fix to ensure namespace scope is inherited.
+- Cleanly exits when syntax warnings/errors are found instead of failing.
+
+2017-03-14 Release 2.4.0
+- Add check_hiera_keys flag for deep checking of Hiera key name correctness. Thanks @petems.
+- Fix Puppet version comparisons for compatibility with Puppet 4.10.
+- Fix app_management setting compatibility with Puppet 5.
+- Refactor PUPPETVERSION usage to Puppet.version public API.
+
+2017-01-30 Release 2.3.0
+- Add app_management flag for Puppet application orchestration support. Thanks @ipcrm.
+- Check all *yaml file extensions, including eyaml. thanks @kjetilho, @rjw1.
+- Only test ERB syntax in files with an *.erb extension. Thanks @alexiri.
+- Extend README to list specific files and checks implemented. Thanks @petems.
+- Refactor Rake filelist generation, add tests. Thanks @kjetilho, @rjw1.
+
 2016-12-02 Release 2.2.0
 - Replace Puppet.initialize_settings with Puppet::Test::TestHelper. Thanks @domcleal #60
   This clears out caches on every test so increases runtime.
diff --git a/Gemfile b/Gemfile
index 4243d162b097b0dabc5d10901449d96582339c9e..1b39064ec00cfa19187ba4070f9c2b93025945fe 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,11 +1,28 @@
 source 'https://rubygems.org'
 
+# Find a location or specific version for a gem. place_or_version can be a
+# version, which is most often used. It can also be git, which is specified as
+# `git://somewhere.git#branch`. You can also use a file source location, which
+# is specified as `file://some/location/on/disk`.
+def location_for(place_or_version, fake_version = nil)
+  if place_or_version =~ /^(git[:@][^#]*)#(.*)/
+    [fake_version, { :git => $1, :branch => $2, :require => false }].compact
+  elsif place_or_version =~ /^file:\/\/(.*)/
+    ['>= 0', { :path => File.expand_path($1), :require => false }]
+  else
+    [place_or_version, { :require => false }]
+  end
+end
+
 # Specify your gem's dependencies in puppet-syntax.gemspec
 gemspec
 
 # Override gemspec for CI matrix builds.
-puppet_version = ENV['PUPPET_VERSION'] || '>2.7.0'
-gem 'puppet', puppet_version
+gem 'puppet', *location_for(ENV['PUPPET_VERSION'] || '>2.7.0')
 
 # older version required for ruby 1.9 compat, as it is pulled in as dependency of puppet, this has to be carried by the module
 gem 'json_pure', '<= 2.0.1'
+
+group :test do
+  gem 'rspec'
+end
\ No newline at end of file
diff --git a/README.md b/README.md
index 2a66bfdb1163a59f2fe3961588a2a7d6e411a047..8a603be37b41c60e165f7a91a8a9187470500c4b 100644
--- a/README.md
+++ b/README.md
@@ -1,88 +1,139 @@
-[![Build Status](https://travis-ci.org/gds-operations/puppet-syntax.svg?branch=master)](https://travis-ci.org/gds-operations/puppet-syntax)
+[![Build Status](https://travis-ci.org/voxpupuli/puppet-syntax.svg?branch=master)](https://travis-ci.org/voxpupuli/puppet-syntax)
 
 # Puppet::Syntax
 
-Syntax checks for Puppet manifests, templates, and Hiera YAML.
+Puppet::Syntax checks for correct syntax in Puppet manifests, templates, and Hiera YAML.
 
 ## Version support
 
-This should work on any version of:
+Puppet::Syntax is supported with:
 
 - Puppet >= 2.7 that provides the `validate` face.
-- Ruby >= 1.8 with `erb` from stdlib.
+- Ruby >= 1.8 with `erb` from Ruby stdlib.
 
-You can see the matrix of specific versions that we currently test against
-in the [TravisCI config](.travis.yml).
+For the specific versions that we test against, see the [TravisCI config](.travis.yml).
 
-If you're using `puppetlabs_spec_helper/rake_tasks` and getting unexpected
-non-zero exit codes then you should upgrade to [puppetlabs_spec_helper][psh]
-\>= 0.8.0 which no longer has a conflicting rake task and now depends on
-this project.
+If you're using `puppetlabs_spec_helper/rake_tasks` and getting unexpected non-zero exit codes, upgrade to [puppetlabs_spec_helper][psh] version 0.8.0 or greater. Versions of `puppetlabs_spec_helper` prior to 0.8.0 conflicted with Puppet::Syntax.
 
 [psh]: https://github.com/puppetlabs/puppetlabs_spec_helper
 
+## Installation
+
+To install Puppet::Syntax, either add it to your module's Gemfile or install the gem manually.
+
+* To install with the Gemfile, add:
+
+        gem 'puppet-syntax'
+
+  And then execute:
+
+        $ bundle install
+
+* To install the gem yourself, run:
+
+        $ gem install puppet-syntax
+
+## Configuration
+
+To configure Puppet::Syntax, add any of the following settings to your `Rakefile`.
+
+* To exclude certain paths from the syntax checks, set:
+
+        PuppetSyntax.exclude_paths = ["vendor/**/*"]
+
+* To use the Puppet 4 ("future") parser in Puppet 3.2 through 3.8, set:
+
+        PuppetSyntax.future_parser = true
+
+* To configure specific paths for the Hiera syntax check, specify `hieradata_paths`. This is useful if you use Hiera data inside your module.
+
+        PuppetSyntax.hieradata_paths = ["**/data/**/*.yaml", "hieradata/**/*.yaml", "hiera*.yaml"]
+
+* To validate the syntax of code written for application orchestration, enable `app_management`:
+
+        PuppetSyntax.app_management = true
+
+  The `app_management` setting is supported with Puppet 4.3 or greater and is off by default. In Puppet 5, app_management is always enabled.
+
+* To ignore deprecation warnings, disable `fail_on_deprecation_notices`. By default, `puppet-syntax` fails if it encounters Puppet deprecation notices. If you are working with a legacy code base and want to ignore such non-fatal warnings, you might want to override the default behavior.
+
+        PuppetSyntax.fail_on_deprecation_notices = false
+
+* To enable a syntax check on Hiera keys, set:
+
+        PuppetSyntax.check_hiera_keys = true
+
+   This reports common mistakes in key names in Hiera files, such as:
+
+  - Leading `::` in keys, such as: `::notsotypical::warning2: true`.
+  - Single colon scope separators, such as: `:picky::warning5: true`.
+  - Invalid camel casing, such as: `noCamelCase::warning3: true`.
+  - Use of hyphens, such as: `no-hyphens::warning4: true`.
+
 ## Usage
 
-Include the following in your `Rakefile`:
+* To enable Puppet::Syntax, include the following in your module's `Rakefile`:
 
-    require 'puppet-syntax/tasks/puppet-syntax'
+        require 'puppet-syntax/tasks/puppet-syntax'
 
-Test all manifests and templates relative to your `Rakefile`:
+  For Continuous Integration, use Puppet::Syntax in conjunction with `puppet-lint` and spec tests. Add the following to your module's `Rakefile`:
 
-    ➜  puppet git:(master) bundle exec rake syntax
-    ---> syntax:manifests
-    ---> syntax:templates
-    ---> syntax:hiera:yaml
+        task :test => [
+          :syntax,
+          :lint,
+          :spec,
+        ]
 
-A non-zero exit code and error message will be returned for any failures:
+* To test all manifests and templates, relative to the location of the `Rakefile`, run:
 
-    ➜  puppet git:(master) bundle exec rake syntax
-    ---> syntax:manifests
-    rake aborted!
-    Could not parse for environment production: Syntax error at end of file at demo.pp:2
-    Tasks: TOP => syntax => syntax:manifests
-    (See full trace by running task with --trace)
+        $ bundle exec rake syntax
+        ---> syntax:manifests
+        ---> syntax:templates
+        ---> syntax:hiera:yaml
 
-Use in conjunction with lint and spec tests for Continuous Integration:
+* To return a non-zero exit code and an error message on any failures, run:
 
-    task :test => [
-      :syntax,
-      :lint,
-      :spec,
-    ]
+        $ bundle exec rake syntax
+        ---> syntax:manifests
+        rake aborted!
+        Could not parse for environment production: Syntax error at end of file at demo.pp:2
+        Tasks: TOP => syntax => syntax:manifests
+        (See full trace by running task with --trace)
 
-## Configuration
+## Checks
 
-Paths can be excluded with:
+Puppet::Syntax makes the following checks in the directories and subdirectories of the module, relative to the location of the `Rakefile`.
 
-    PuppetSyntax.exclude_paths = ["vendor/**/*"]
+### Hiera
 
-When you are using a Puppet version greater then 3.2, you can select the future parse by specifying
+Checks `.yaml` files for syntax errors.
 
-    PuppetSyntax.future_parser = true
+By default, this rake task looks for all `.yaml` files in a single module under:
 
-If you are using some form of hiera data inside your module, you can configure where the `syntax:hiera:yaml` task looks for data with:
+* `**/data/**/*.yaml`
+* `hieradata/**/*.yaml`
+* `hiera*.yaml`
 
-    PuppetSyntax.hieradata_paths = ["**/data/**/*.yaml", "hieradata/**/*.yaml", "hiera*.yaml"]
+### manifests
 
-## Installation
+Checks all `.pp` files in the module for syntax errors.
 
-Add this line to your application's Gemfile:
+### templates
 
-    gem 'puppet-syntax'
+#### erb
 
-And then execute:
+Checks `.erb` files in the module for syntax errors.
 
-    $ bundle
+#### epp
 
-Or install it yourself as:
+Checks `.epp` files in the module for syntax errors.
 
-    $ gem install puppet-syntax
+EPP checks are supported in Puppet 4 or greater, or in Puppet 3 with the future parser enabled.
 
 ## Contributing
 
-1. Fork it
-2. Create your feature branch (`git checkout -b my-new-feature`)
-3. Commit your changes (`git commit -am 'Add some feature'`)
-4. Push to the branch (`git push origin my-new-feature`)
-5. Create new Pull Request
+1. Fork the repo.
+2. Create your feature branch (`git checkout -b my-new-feature`).
+3. Commit your changes (`git commit -am 'Add some feature'`).
+4. Push to the branch (`git push origin my-new-feature`).
+5. Create new Pull Request.
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 0000000000000000000000000000000000000000..eaf11f4fbaf07a700774520d8215db24a09b72e5
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,38 @@
+build: off
+
+branches:
+  only:
+    - master
+
+# ruby versions under test
+environment:
+  matrix:
+    - RUBY_VERSION: 21
+      PUPPET_VERSION: "~> 3.8.7"
+    - RUBY_VERSION: 21
+      PUPPET_VERSION: "~> 4.8.0"
+    - RUBY_VERSION: 23-x64
+      PUPPET_VERSION: "~> 4.9.0"
+    - RUBY_VERSION: 23-x64
+      PUPPET_VERSION: "> 0"
+    - RUBY_VERSION: 23-x64
+      PUPPET_VERSION: "git://github.com/puppetlabs/puppet.git#master"
+
+matrix:
+  allow_failures:
+    - RUBY_VERSION: 23-x64
+      PUPPET_VERSION: "git://github.com/puppetlabs/puppet.git#master"
+      
+install:
+  - SET PATH=C:\Ruby%RUBY_VERSION%\bin;%PATH%
+  - SET LOG_SPEC_ORDER=true
+  - bundle install --jobs 4 --retry 2 --without development
+
+before_test:
+  - type Gemfile.lock
+  - ruby -v
+  - gem -v
+  - bundle -v
+
+test_script:
+  - bundle exec rake spec
diff --git a/lib/puppet-syntax.rb b/lib/puppet-syntax.rb
index 65aa45663018ab7886ff102a016b3d5cd61058f8..98f83f930d9aa3117231a43065a6ebc48eb466ae 100644
--- a/lib/puppet-syntax.rb
+++ b/lib/puppet-syntax.rb
@@ -2,14 +2,32 @@ require "puppet-syntax/version"
 require "puppet-syntax/manifests"
 require "puppet-syntax/templates"
 require "puppet-syntax/hiera"
+require "puppet/version"
 
 module PuppetSyntax
   @exclude_paths = []
   @future_parser = false
-  @hieradata_paths = ["**/data/**/*.yaml", "hieradata/**/*.yaml", "hiera*.yaml"]
+  @hieradata_paths = [
+    "**/data/**/*.*yaml",
+    "hieradata/**/*.*yaml",
+    "hiera*.*yaml"
+  ]
   @fail_on_deprecation_notices = true
+  @app_management = Puppet.version.to_i >= 5 ? true : false
+  @check_hiera_keys = false
 
   class << self
-    attr_accessor :exclude_paths, :future_parser, :hieradata_paths, :fail_on_deprecation_notices, :epp_only
+    attr_accessor :exclude_paths,
+                  :future_parser,
+                  :hieradata_paths,
+                  :fail_on_deprecation_notices,
+                  :epp_only,
+                  :check_hiera_keys
+    attr_reader :app_management
+
+    def app_management=(app_management)
+      raise 'app_management cannot be disabled on Puppet 5 or higher' if Puppet.version.to_i >= 5 && !app_management
+      @app_management = app_management
+    end
   end
 end
diff --git a/lib/puppet-syntax/hiera.rb b/lib/puppet-syntax/hiera.rb
index c6f200a0da59cc74e036fda0753ba376a9e03b45..c492ebb1b3e47464c3ba91f5baedf4657e648764 100644
--- a/lib/puppet-syntax/hiera.rb
+++ b/lib/puppet-syntax/hiera.rb
@@ -2,6 +2,24 @@ require 'yaml'
 
 module PuppetSyntax
   class Hiera
+
+    def check_hiera_key(key)
+      if key.is_a? Symbol
+        if key.to_s.start_with?(':')
+          return "Puppet automatic lookup will not use leading '::'"
+        elsif key !~ /^[a-z]+$/ # we allow Hiera's own configuration
+          return "Puppet automatic lookup will not look up symbols"
+        end
+      elsif key !~ /^[a-z][a-z0-9_]+(::[a-z][a-z0-9_]+)*$/
+        if key =~ /[^:]:[^:]/
+          # be extra helpful
+          return "Looks like a missing colon"
+        else
+          return "Not a valid Puppet variable name for automatic lookup"
+        end
+      end
+    end
+
     def check(filelist)
       raise "Expected an array of files" unless filelist.is_a?(Array)
 
@@ -9,11 +27,20 @@ module PuppetSyntax
 
       filelist.each do |hiera_file|
         begin
-          YAML.load_file(hiera_file)
+          yamldata = YAML.load_file(hiera_file)
         rescue Exception => error
           errors << "ERROR: Failed to parse #{hiera_file}: #{error}"
+          next
+        end
+        if yamldata
+          yamldata.each do |k,v|
+            if PuppetSyntax.check_hiera_keys
+              key_msg = check_hiera_key(k)
+              errors << "WARNING: #{hiera_file}: Key :#{k}: #{key_msg}" if key_msg
+            end
+          end
         end
-       end
+      end
 
       errors.map! { |e| e.to_s }
 
diff --git a/lib/puppet-syntax/manifests.rb b/lib/puppet-syntax/manifests.rb
index 821fc054933078b1e6463fba902483cbf787b193..505ab33ea4cd703254ce191d336e580d184bafa1 100644
--- a/lib/puppet-syntax/manifests.rb
+++ b/lib/puppet-syntax/manifests.rb
@@ -58,7 +58,8 @@ module PuppetSyntax
 
     private
     def validate_manifest(file)
-      Puppet[:parser] = 'future' if PuppetSyntax.future_parser and Puppet::PUPPETVERSION.to_i < 4
+      Puppet[:parser] = 'future' if PuppetSyntax.future_parser and Puppet.version.to_i < 4
+      Puppet[:app_management] = true if PuppetSyntax.app_management && (Puppet::Util::Package.versioncmp(Puppet.version, '4.3.0') >= 0 && Puppet.version.to_i < 5)
       Puppet::Face[:parser, :current].validate(file)
     end
   end
diff --git a/lib/puppet-syntax/tasks/puppet-syntax.rb b/lib/puppet-syntax/tasks/puppet-syntax.rb
index 4af27a1b1887b788f1d64b299548aa4639fec451..c8a14303d2e9faa30fd3886a73b54b7c6d5f552a 100644
--- a/lib/puppet-syntax/tasks/puppet-syntax.rb
+++ b/lib/puppet-syntax/tasks/puppet-syntax.rb
@@ -4,6 +4,24 @@ require 'rake/tasklib'
 
 module PuppetSyntax
   class RakeTask < ::Rake::TaskLib
+    def filelist(paths)
+      files = FileList[paths]
+      files.reject! { |f| File.directory?(f) }
+      files.exclude(*PuppetSyntax.exclude_paths)
+    end
+
+    def filelist_manifests
+      filelist("**/*.pp")
+    end
+
+    def filelist_templates
+      filelist(["**/templates/**/*.erb", "**/templates/**/*.epp"])
+    end
+
+    def filelist_hiera_yaml
+      filelist(PuppetSyntax.hieradata_paths)
+    end
+
     def initialize(*args)
       desc 'Syntax check Puppet manifests and templates'
       task :syntax => [
@@ -15,7 +33,7 @@ module PuppetSyntax
 
       namespace :syntax do
         task :check_puppetlabs_spec_helper do
-          psh_present = Rake::Task[:syntax].actions.any? { |a|
+          psh_present = task(:syntax).actions.any? { |a|
             a.inspect.match(/puppetlabs_spec_helper\/rake_tasks\.rb:\d+/)
           }
 
@@ -30,33 +48,35 @@ to puppetlabs_spec_helper >= 0.8.0 which now uses puppet-syntax.
 
         desc 'Syntax check Puppet manifests'
         task :manifests do |t|
-          if Puppet::PUPPETVERSION.to_i >= 4 and PuppetSyntax.future_parser
+          if Puppet.version.to_i >= 4 and PuppetSyntax.future_parser
             $stderr.puts <<-EOS
 [INFO] Puppet 4 has been detected and `future_parser` has been set to
 'true'. The `future_parser setting will be ignored.
             EOS
           end
+          if Puppet::Util::Package.versioncmp(Puppet.version, '4.3.0') < 0 and PuppetSyntax.app_management
+            $stderr.puts <<-EOS
+[WARNING] Puppet `app_management` has been detected but the Puppet
+version is less then 4.3.  The `app_management` setting will be ignored.
+            EOS
+          end
+
           $stderr.puts "---> #{t.name}"
-          files = FileList["**/*.pp"]
-          files.reject! { |f| File.directory?(f) }
-          files = files.exclude(*PuppetSyntax.exclude_paths)
 
           c = PuppetSyntax::Manifests.new
-          output, has_errors = c.check(files)
-          print "#{output.join("\n")}\n" unless output.empty?
-          fail if has_errors || ( output.any? && PuppetSyntax.fail_on_deprecation_notices )
+          output, has_errors = c.check(filelist_manifests)
+          $stdout.puts "#{output.join("\n")}\n" unless output.empty?
+          exit 1 if has_errors || ( output.any? && PuppetSyntax.fail_on_deprecation_notices )
         end
 
         desc 'Syntax check Puppet templates'
         task :templates do |t|
           $stderr.puts "---> #{t.name}"
-          files = FileList["**/templates/**/*"]
-          files.reject! { |f| File.directory?(f) }
-          files = files.exclude(*PuppetSyntax.exclude_paths)
 
           c = PuppetSyntax::Templates.new
-          errors = c.check(files)
-          fail errors.join("\n") unless errors.empty?
+          errors = c.check(filelist_templates)
+          $stdout.puts "#{errors.join("\n")}\n" unless errors.empty?
+          exit 1 unless errors.empty?
         end
 
         desc 'Syntax check Hiera config files'
@@ -67,13 +87,10 @@ to puppetlabs_spec_helper >= 0.8.0 which now uses puppet-syntax.
         namespace :hiera do
           task :yaml do |t|
             $stderr.puts "---> #{t.name}"
-            files = FileList.new(PuppetSyntax.hieradata_paths)
-            files.reject! { |f| File.directory?(f) }
-            files = files.exclude(*PuppetSyntax.exclude_paths)
-
             c = PuppetSyntax::Hiera.new
-            errors = c.check(files)
-            fail errors.join("\n") unless errors.empty?
+            errors = c.check(filelist_hiera_yaml)
+            $stdout.puts "#{errors.join("\n")}\n" unless errors.empty?
+            exit 1 unless errors.empty?
           end
         end
       end
diff --git a/lib/puppet-syntax/templates.rb b/lib/puppet-syntax/templates.rb
index 25257b4b3b9da96754d89a339c8c9e2569bb93bc..c62a70649b659546e7628c4e4e3b2ec1af6f26dd 100644
--- a/lib/puppet-syntax/templates.rb
+++ b/lib/puppet-syntax/templates.rb
@@ -14,7 +14,7 @@ module PuppetSyntax
       filelist.each do |file|
         if File.extname(file) == '.epp' or PuppetSyntax.epp_only
           errors.concat validate_epp(file)
-        else
+        elsif File.extname(file) == '.erb'
           errors.concat validate_erb(file)
         end
       end
@@ -27,7 +27,7 @@ module PuppetSyntax
     end
 
     def validate_epp(filename)
-      if Puppet::PUPPETVERSION.to_f < 3.7
+      if Puppet.version.to_f < 3.7
         raise "Cannot validate EPP without Puppet 4 or future parser (3.7+)"
       end
 
diff --git a/lib/puppet-syntax/version.rb b/lib/puppet-syntax/version.rb
index d3de70c13969250d2bde73d013816479fffd2a7d..d339b66b17b765213a8bd2fa6f8b347058a77dfc 100644
--- a/lib/puppet-syntax/version.rb
+++ b/lib/puppet-syntax/version.rb
@@ -1,3 +1,3 @@
 module PuppetSyntax
-  VERSION = "2.2.0"
+  VERSION = "2.4.1"
 end
diff --git a/puppet-syntax.gemspec b/puppet-syntax.gemspec
index f84147c58b5b7abbc14aa0f547b136f5bcf885e2..7731acf46cefc0402c7ba64f5562375064a1f393 100644
--- a/puppet-syntax.gemspec
+++ b/puppet-syntax.gemspec
@@ -6,11 +6,11 @@ require 'puppet-syntax/version'
 Gem::Specification.new do |spec|
   spec.name          = "puppet-syntax"
   spec.version       = PuppetSyntax::VERSION
-  spec.authors       = ["Dan Carley"]
-  spec.email         = ["dan.carley@gmail.com"]
+  spec.authors       = ["Vox Pupuli"]
+  spec.email         = ["voxpupuli@groups.io"]
   spec.description   = %q{Syntax checks for Puppet manifests and templates}
   spec.summary       = %q{Syntax checks for Puppet manifests, templates, and Hiera YAML}
-  spec.homepage      = "https://github.com/gds-operations/puppet-syntax"
+  spec.homepage      = "https://github.com/voxpupuli/puppet-syntax"
   spec.license       = "MIT"
 
   spec.files         = `git ls-files`.split($/)
@@ -20,6 +20,7 @@ Gem::Specification.new do |spec|
 
   spec.add_dependency "rake"
 
-  spec.add_development_dependency "rspec"
+  spec.add_development_dependency "pry"
+  spec.add_development_dependency "rb-readline"
   spec.add_development_dependency "gem_publisher", "~> 1.3"
 end
diff --git a/spec/fixtures/hiera/data/hiera_1.yaml b/spec/fixtures/hiera/data/hiera_1.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/spec/fixtures/hiera/data/hiera_2.eyaml b/spec/fixtures/hiera/data/hiera_2.eyaml
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/spec/fixtures/hiera/data/test/hiera_3.yaml b/spec/fixtures/hiera/data/test/hiera_3.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/spec/fixtures/hiera/data/test/hiera_4.eyaml b/spec/fixtures/hiera/data/test/hiera_4.eyaml
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/spec/fixtures/hiera/hiera_badkey.yaml b/spec/fixtures/hiera/hiera_badkey.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..d1f45f48b9fd9f3117a34f1c7898c931050777b7
--- /dev/null
+++ b/spec/fixtures/hiera/hiera_badkey.yaml
@@ -0,0 +1,11 @@
+---
+this_is_ok: 0
+this_is_ok::too: 0
+th1s_is_ok::two3: 0
+:eventhis: 0
+
+typical:typo::warning1:   true
+::notsotypical::warning2: true
+noCamelCase::warning3:    true
+no-hyphens::warning4:     true
+:picky::warning5:         true
diff --git a/spec/fixtures/hiera/hiera_key_empty.yaml b/spec/fixtures/hiera/hiera_key_empty.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/spec/fixtures/test_module/manifests/test_app.pp b/spec/fixtures/test_module/manifests/test_app.pp
new file mode 100644
index 0000000000000000000000000000000000000000..e15d502130321b946fa9d3e493f9664da7c98afa
--- /dev/null
+++ b/spec/fixtures/test_module/manifests/test_app.pp
@@ -0,0 +1,3 @@
+application test_app {
+
+}
diff --git a/spec/fixtures/test_module/templates/ignore.tpl b/spec/fixtures/test_module/templates/ignore.tpl
new file mode 100644
index 0000000000000000000000000000000000000000..31ea616157f87f6b37d064802320f91cea38394d
--- /dev/null
+++ b/spec/fixtures/test_module/templates/ignore.tpl
@@ -0,0 +1,3 @@
+This is plain text
+<% This is not valid Ruby %>
+This is also plain text
diff --git a/spec/puppet-syntax/hiera_spec.rb b/spec/puppet-syntax/hiera_spec.rb
index 8e750522ac48131a52cf6c83099fdc368a42f3ed..5662698c34cd1ef5b0369d2fdb649d59b88c5646 100644
--- a/spec/puppet-syntax/hiera_spec.rb
+++ b/spec/puppet-syntax/hiera_spec.rb
@@ -21,4 +21,34 @@ describe PuppetSyntax::Hiera do
     expect(res.size).to be == 1
     expect(res.first).to match(expected)
   end
+
+  context 'check_hiera_keys = true' do
+    before(:each) {
+      PuppetSyntax.check_hiera_keys = true
+    }
+
+    it "should return warnings for invalid keys" do
+      hiera_yaml = 'hiera_badkey.yaml'
+      examples = 5
+      files = fixture_hiera(hiera_yaml)
+      res = subject.check(files)
+      (1..examples).each do |n|
+        expect(res).to include(/::warning#{n}/)
+      end
+      expect(res.size).to be == examples
+      expect(res[0]).to match('Key :typical:typo::warning1: Looks like a missing colon')
+      expect(res[1]).to match('Key ::notsotypical::warning2: Puppet automatic lookup will not use leading \'::\'')
+      expect(res[2]).to match('Key :noCamelCase::warning3: Not a valid Puppet variable name for automatic lookup')
+      expect(res[3]).to match('Key :no-hyphens::warning4: Not a valid Puppet variable name for automatic lookup')
+      expect(res[4]).to match('Key :picky::warning5: Puppet automatic lookup will not look up symbols')
+    end
+
+    it "should handle empty files" do
+      hiera_yaml = 'hiera_key_empty.yaml'
+      files = fixture_hiera(hiera_yaml)
+      res = subject.check(files)
+      expect(res).to be_empty
+    end
+
+  end
 end
diff --git a/spec/puppet-syntax/manifests_spec.rb b/spec/puppet-syntax/manifests_spec.rb
index 738b99bdc5425c651caad577bfaeeefef847ec56..69d8d51e20f560630b0a64128360ff7948ed9dcb 100644
--- a/spec/puppet-syntax/manifests_spec.rb
+++ b/spec/puppet-syntax/manifests_spec.rb
@@ -28,9 +28,9 @@ describe PuppetSyntax::Manifests do
     files = fixture_manifests('fail_error.pp')
     output, has_errors = subject.check(files)
 
-    if Puppet::PUPPETVERSION.to_i >= 4
+    if Puppet.version.to_i >= 4
       expect(output.size).to eq(3)
-      expect(output[2]).to match(/Found 2 errors. Giving up/)
+      expect(output[2]).to match(/2 errors. Giving up/)
       expect(has_errors).to eq(true)
     else
       expect(output.size).to eq(1)
@@ -72,11 +72,11 @@ describe PuppetSyntax::Manifests do
     output, has_errors = subject.check(files)
 
     expect(has_errors).to eq(true)
-    if Puppet::PUPPETVERSION.to_i >= 4
+    if Puppet.version.to_i >= 4
       expect(output.size).to eq(5)
       expect(output[0]).to match(/This Name has no effect. A Host Class Definition can not end with a value-producing expression without other effect at \S*\/fail_error.pp:2:32$/)
       expect(output[1]).to match(/This Name has no effect. A value(-producing expression without other effect may only be placed last in a block\/sequence| was produced and then forgotten.*) at \S*\/fail_error.pp:2:3$/)
-      expect(output[2]).to match('Found 2 errors. Giving up')
+      expect(output[2]).to match('2 errors. Giving up')
       expect(output[3]).to match(/Unrecogni(s|z)ed escape sequence '\\\['/)
       expect(output[4]).to match(/Unrecogni(s|z)ed escape sequence '\\\]'/)
     else
@@ -136,6 +136,50 @@ describe PuppetSyntax::Manifests do
     end
   end
 
+  describe 'app_management' do
+    after do
+      PuppetSyntax.app_management = false if Puppet.version.to_i < 5
+    end
+
+    context 'app_management = false (default)', :if => (Puppet.version.to_i < 5) do
+      it 'should fail to parse an application manifest' do
+
+        files = fixture_manifests(['test_app.pp'])
+        output,has_errors = subject.check(files)
+
+        expect(has_errors).to eq(true)
+        expect(output).to include(/error/)
+      end
+    end
+    context 'app_management = true' do
+      before(:each) {
+        PuppetSyntax.app_management = true
+      }
+      if Puppet::Util::Package.versioncmp(Puppet.version, '4.3.0') >= 0
+        it 'should successfully parse an application manifest on Puppet >= 4.3.0' do
+          expect(PuppetSyntax.app_management).to eq(true)
+
+          files = fixture_manifests(['test_app.pp'])
+          output,has_errors = subject.check(files)
+
+          expect(output.size).to eq(0)
+          expect(has_errors).to eq(false)
+        end
+      else
+        it 'should fail to parse an application manifest on Puppet < 4.3.0' do
+          expect(PuppetSyntax.app_management).to eq(true)
+
+          files = fixture_manifests(['test_app.pp'])
+          output,has_errors = subject.check(files)
+
+          expect(output).to include(/error/)
+          expect(has_errors).to eq(true)
+        end
+      end
+    end
+  end
+
+
   describe 'future_parser' do
     context 'future_parser = false (default)' do
       if Puppet::Util::Package.versioncmp(Puppet.version, '4.0') < 0
@@ -167,7 +211,7 @@ describe PuppetSyntax::Manifests do
         PuppetSyntax.future_parser = true
       }
 
-      if Puppet::Util::Package.versioncmp(Puppet.version, '3.2') >= 0 and Puppet::PUPPETVERSION.to_i < 4
+      if Puppet::Util::Package.versioncmp(Puppet.version, '3.2') >= 0 and Puppet.version.to_i < 4
         context 'Puppet >= 3.2 < 4' do
           it 'should pass with future option set to true on future manifest' do
             files = fixture_manifests(['future_syntax.pp'])
diff --git a/spec/puppet-syntax/tasks/puppet-syntax_spec.rb b/spec/puppet-syntax/tasks/puppet-syntax_spec.rb
index e3be1670a40734188ddf15d01d4b2cb064ccb888..f1117c9a408f9cb7f046735bd525a0ab22b0bc5d 100644
--- a/spec/puppet-syntax/tasks/puppet-syntax_spec.rb
+++ b/spec/puppet-syntax/tasks/puppet-syntax_spec.rb
@@ -1,8 +1,42 @@
 require 'spec_helper'
 require 'puppet-syntax/tasks/puppet-syntax'
 
+known_pp = 'spec/fixtures/test_module/manifests/pass.pp'
+known_erb = 'spec/fixtures/test_module/templates/pass.erb'
+known_yaml = 'spec/fixtures/hiera/data/hiera_1.yaml'
+known_eyaml = 'spec/fixtures/hiera/data/hiera_2.eyaml'
+known_yaml_subdir = 'spec/fixtures/hiera/data/test/hiera_3.yaml'
+known_eyaml_subdir = 'spec/fixtures/hiera/data/test/hiera_4.eyaml'
+
 describe 'PuppetSyntax rake tasks' do
+  it 'should filter directories' do
+    list = PuppetSyntax::RakeTask.new.filelist(['**/lib', known_pp])
+    expect(list.count).to eq 1
+    expect(list).to include(known_pp)
+  end
+
   it 'should generate FileList of manifests relative to Rakefile' do
+    list = PuppetSyntax::RakeTask.new.filelist_manifests
+    expect(list).to include(known_pp)
+    expect(list.count).to eq 8
+  end
+
+  it 'should generate FileList of templates relative to Rakefile' do
+    list = PuppetSyntax::RakeTask.new.filelist_templates
+    expect(list).to include(known_erb)
+    expect(list.count).to eq 9
+  end
+
+  it 'should generate FileList of Hiera yaml files relative to Rakefile' do
+    list = PuppetSyntax::RakeTask.new.filelist_hiera_yaml
+    expect(list).to include(known_yaml)
+    expect(list).to include(known_eyaml)
+    expect(list).to include(known_yaml_subdir)
+    expect(list).to include(known_eyaml_subdir)
+    expect(list.count).to eq 4
+  end
+
+  it 'should check manifests relative to Rakefile' do
     if RSpec::Version::STRING < '3'
       pending
     else
@@ -10,11 +44,12 @@ describe 'PuppetSyntax rake tasks' do
     end
   end
 
-  it 'should generate FileList of templates relative to Rakefile' do
+  it 'should check templates relative to Rakefile' do
     if RSpec::Version::STRING < '3'
       pending
     else
       skip('needs to be done')
     end
   end
+
 end
diff --git a/spec/puppet-syntax/templates_spec.rb b/spec/puppet-syntax/templates_spec.rb
index ade5d6068eb17764295de25f61345c95c661e828..cb97a1663d9effcb8c12a4f23fa5a2294939b0b8 100644
--- a/spec/puppet-syntax/templates_spec.rb
+++ b/spec/puppet-syntax/templates_spec.rb
@@ -60,7 +60,14 @@ describe PuppetSyntax::Templates do
     expect(res).to match([])
   end
 
-  if Puppet::PUPPETVERSION.to_f < 3.7
+  it 'should ignore files without .erb extension' do
+    files = fixture_templates('ignore.tpl')
+    res = subject.check(files)
+
+    expect(res).to match([])
+  end
+
+  if Puppet.version.to_f < 3.7
     context 'on Puppet < 3.7' do
       it 'should throw an exception when parsing EPP files' do
         file = fixture_templates('pass.epp')
@@ -80,7 +87,7 @@ describe PuppetSyntax::Templates do
     end
   end
 
-  if Puppet::PUPPETVERSION.to_f >= 3.7
+  if Puppet.version.to_f >= 3.7
     context 'on Puppet >= 3.7' do
       it 'should return nothing from a valid file' do
         files = fixture_templates('pass.epp')
diff --git a/spec/puppet-syntax_spec.rb b/spec/puppet-syntax_spec.rb
index 7ab5d2289e151a20e744c062facd70f19c9f5096..fe85b5475ded6ed74092d147937c95142edd7abb 100644
--- a/spec/puppet-syntax_spec.rb
+++ b/spec/puppet-syntax_spec.rb
@@ -3,6 +3,7 @@ require 'spec_helper'
 describe PuppetSyntax do
   after do
     PuppetSyntax.exclude_paths = []
+    PuppetSyntax.app_management = false if Puppet.version.to_i < 5
   end
 
   it 'should default exclude_paths to empty array' do
@@ -24,6 +25,15 @@ describe PuppetSyntax do
     expect(PuppetSyntax.future_parser).to eq(true)
   end
 
+  it 'should support app_management setting setting' do
+    PuppetSyntax.app_management = true
+    expect(PuppetSyntax.app_management).to eq(true)
+  end
+
+  it 'should raise error when app_management is disabled on 5.x', :if => (Puppet.version.to_i >= 5) do
+    expect { PuppetSyntax.app_management = false }.to raise_error(/app_management cannot be disabled on Puppet 5 or higher/)
+  end
+
   it 'should support a fail_on_deprecation_notices setting' do
     PuppetSyntax.fail_on_deprecation_notices = false
     expect(PuppetSyntax.fail_on_deprecation_notices).to eq(false)