# File lib/puppet/util/provider_features.rb, line 105
105:   def feature_module
106:     unless defined?(@feature_module)
107:       @features ||= {}
108:       @feature_module = ::Module.new
109:       const_set("FeatureModule", @feature_module)
110:       features = @features
111:       # Create a feature? method that can be passed a feature name and
112:       # determine if the feature is present.
113:       @feature_module.send(:define_method, :feature?) do |name|
114:         method = name.to_s + "?"
115:         return !!(respond_to?(method) and send(method))
116:       end
117: 
118:       # Create a method that will list all functional features.
119:       @feature_module.send(:define_method, :features) do
120:         return false unless defined?(features)
121:         features.keys.find_all { |n| feature?(n) }.sort { |a,b|
122:           a.to_s <=> b.to_s
123:         }
124:       end
125: 
126:       # Create a method that will determine if a provided list of
127:       # features are satisfied by the curred provider.
128:       @feature_module.send(:define_method, :satisfies?) do |*needed|
129:         ret = true
130:         needed.flatten.each do |feature|
131:           unless feature?(feature)
132:             ret = false
133:             break
134:           end
135:         end
136:         ret
137:       end
138: 
139:       # Create a boolean method for each feature so you can test them
140:       # individually as you might need.
141:       @features.each do |name, feature|
142:         method = name.to_s + "?"
143:         @feature_module.send(:define_method, method) do
144:           (is_a?(Class) ?  declared_feature?(name) : self.class.declared_feature?(name)) or feature.available?(self)
145:         end
146:       end
147: 
148:       # Allow the provider to declare that it has a given feature.
149:       @feature_module.send(:define_method, :has_features) do |*names|
150:         @declared_features ||= []
151:         names.each do |name|
152:           name = symbolize(name)
153:           @declared_features << name
154:         end
155:       end
156:       # Aaah, grammatical correctness
157:       @feature_module.send(:alias_method, :has_feature, :has_features)
158:     end
159:     @feature_module
160:   end