# File lib/puppet/resource/catalog.rb, line 208
208:   def extract
209:     top = nil
210:     current = nil
211:     buckets = {}
212: 
213:     unless main = resource(:stage, "main")
214:       raise Puppet::DevError, "Could not find 'main' stage; cannot generate catalog"
215:     end
216: 
217:     if stages = vertices.find_all { |v| v.type == "Stage" and v.title != "main" } and ! stages.empty?
218:       Puppet.warning "Stages are not supported by 0.24.x client; stage(s) #{stages.collect { |s| s.to_s }.join(', ') } will be ignored"
219:     end
220: 
221:     bucket = nil
222:     walk(main, :out) do |source, target|
223:       # The sources are always non-builtins.
224:       unless tmp = buckets[source.to_s]
225:         if tmp = buckets[source.to_s] = source.to_trans
226:           bucket = tmp
227:         else
228:           # This is because virtual resources return nil.  If a virtual
229:           # container resource contains realized resources, we still need to get
230:           # to them.  So, we keep a reference to the last valid bucket
231:           # we returned and use that if the container resource is virtual.
232:         end
233:       end
234:       bucket = tmp || bucket
235:       if child = target.to_trans
236:         raise "No bucket created for #{source}" unless bucket
237:         bucket.push child
238: 
239:         # It's important that we keep a reference to any TransBuckets we've created, so
240:         # we don't create multiple buckets for children.
241:         buckets[target.to_s] = child unless target.builtin?
242:       end
243:     end
244: 
245:     # Retrieve the bucket for the top-level scope and set the appropriate metadata.
246:     unless result = buckets[main.to_s]
247:       # This only happens when the catalog is entirely empty.
248:       result = buckets[main.to_s] = main.to_trans
249:     end
250: 
251:     result.classes = classes
252: 
253:     # Clear the cache to encourage the GC
254:     buckets.clear
255:     result
256:   end