/// <summary>
        /// Resolves the plugins of an extension from a fragment.
        /// </summary>
        /// <param name="parsedFragment">The partially parsed extension.</param>
        /// <returns>The plugins of the extension</returns>
        /// <exception cref="GeneratorException">A plugin must contain exactly one model.</exception>
        public static List<Typo3ExtensionGenerator.Model.Plugin.Plugin> Resolve( Fragment parsedFragment )
        {
            IEnumerable<Fragment> pluginPartials = parsedFragment.Fragments.Where( p => p.Keyword == Keywords.ExtensionDirectives.DeclarePlugin );
              if( !pluginPartials.Any() ) return null;

              List<Typo3ExtensionGenerator.Model.Plugin.Plugin> plugins = new List<Typo3ExtensionGenerator.Model.Plugin.Plugin>();
              foreach( Fragment pluginPartial in pluginPartials ) {
            // Construct the plugin with the given name
            Typo3ExtensionGenerator.Model.Plugin.Plugin plugin = new Typo3ExtensionGenerator.Model.Plugin.Plugin
                                                             {Name = pluginPartial.Parameters,SourceFragment = pluginPartial };

            // Find the data models that are defined for this plugin
            List<DataModel> dataModels = ModelResolver.Resolve( pluginPartial );
            if( null == dataModels || dataModels.Count > 1 ) {
              throw new GeneratorException( "A plugin must contain exactly one model.", pluginPartial.SourceDocument );
            }
            plugin.Model = dataModels[ 0 ];
            plugin.Model.Name = "flexform";

            // Resolve plugin
            foreach( Fragment pluginParameter in pluginPartial.Fragments ) {
              if( pluginParameter.Keyword == Keywords.Title) {
            plugin.Title = pluginParameter.Parameters;

              } else if( pluginParameter.Keyword == Keywords.DefineInterface ) {
            Typo3ExtensionGenerator.Model.Configuration.Interface.Interface @interface =
              InterfaceResolver.Resolve( pluginParameter );

            @interface.ParentModelTarget = "flexform";
            @interface.ParentModel = plugin.Model;
            plugin.Interfaces.Add( @interface );

              } else if( pluginParameter.Keyword == Keywords.PluginDirectives.Action ) {
            Action action = ActionResolver.ResolveAction( pluginParameter );
            plugin.Actions.Add( action );

              } else if( pluginParameter.Keyword == Keywords.PluginDirectives.Listener ) {
            Listener listener = ListenerResolver.ResolveListener( pluginParameter );
            plugin.Actions.Add( listener.TargetAction );
            plugin.Listeners.Add( listener );

              } else if( pluginParameter.Keyword == Keywords.Implementation ) {
            plugin.Implementation = pluginParameter.Parameters;
              }
            }

            // If no name was defined, use the common placeholder names
            if( string.IsNullOrEmpty( plugin.Name ) ) {
              plugin.Name = string.Format( "Pi{0}", ( plugins.Count + 1 ) );
            }

            plugins.Add( plugin );
              }

              return plugins;
        }
 /// <summary>
 /// Returns a plugin key. Like userdownloads_stats or news_pi1
 /// </summary>
 /// <param name="extension"></param>
 /// <param name="plugin"></param>
 /// <returns></returns>
 public static string GetPluginSignature( Extension extension, Plugin plugin )
 {
     return String.Format( "{0}_{1}", extension.Key.Replace( "_", string.Empty ), plugin.Name.ToLower() );
 }