package org.apache.maven.plugin.testing;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.io.input.XmlStreamReader;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.apache.maven.execution.DefaultMavenExecutionRequest;
import org.apache.maven.execution.DefaultMavenExecutionResult;
import org.apache.maven.execution.MavenExecutionRequest;
import org.apache.maven.execution.MavenExecutionResult;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.lifecycle.internal.MojoDescriptorCreator;
import org.apache.maven.model.Plugin;
import org.apache.maven.monitor.logging.DefaultLog;
import org.apache.maven.plugin.Mojo;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.PluginParameterExpressionEvaluator;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.Parameter;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.plugin.descriptor.PluginDescriptorBuilder;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.project.MavenProject;
import org.apache.maven.repository.RepositorySystem;
import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
import org.codehaus.plexus.ContainerConfiguration;
import org.codehaus.plexus.DefaultContainerConfiguration;
import org.codehaus.plexus.DefaultPlexusContainer;
import org.codehaus.plexus.PlexusConstants;
import org.codehaus.plexus.PlexusContainer;
import org.codehaus.plexus.PlexusContainerException;
import org.codehaus.plexus.PlexusTestCase;
import org.codehaus.plexus.classworlds.ClassWorld;
import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
import org.codehaus.plexus.component.configurator.ComponentConfigurator;
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
import org.codehaus.plexus.component.repository.ComponentDescriptor;
import org.codehaus.plexus.configuration.PlexusConfiguration;
import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
import org.codehaus.plexus.logging.LoggerManager;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.InterpolationFilterReader;
import org.codehaus.plexus.util.ReaderFactory;
import org.codehaus.plexus.util.ReflectionUtils;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.codehaus.plexus.util.xml.Xpp3DomBuilder;

import com.google.inject.Module;

/**
 * TODO: add a way to use the plugin POM for the lookup so that the user doesn't have to provide the a:g:v:goal
 * as the role hint for the mojo lookup.
 * TODO: standardize the execution of the mojo and looking at the results, but could simply have a template method
 * for verifying the state of the mojo post execution
 * TODO: need a way to look at the state of the mojo without adding getters, this could be where we finally specify
 * the expressions which extract values from the mojo.
 * TODO: create a standard directory structure for picking up POMs to make this even easier, we really just need a testing
 * descriptor and make this entirely declarative!
 *
 * @author jesse
 * @version $Id$
 */
public abstract class AbstractMojoTestCase
    extends PlexusTestCase
{
    private static final DefaultArtifactVersion MAVEN_VERSION;

    static
    {
        DefaultArtifactVersion version = null;
        String path = "/META-INF/maven/org.apache.maven/maven-core/pom.properties";
        InputStream is = AbstractMojoTestCase.class.getResourceAsStream( path );
        try
        {
            Properties properties = new Properties();
            if ( is != null )
            {
                properties.load( is );
            }
            String property = properties.getProperty( "version" );
            if ( property != null )
            {
                version = new DefaultArtifactVersion( property );
            }
        }
        catch ( IOException e )
        {
            // odd, where did this come from
        }
        finally
        {
            IOUtil.close( is );
        }
        MAVEN_VERSION = version;
    }

    private ComponentConfigurator configurator;

    private PlexusContainer container;

    private Map<String, MojoDescriptor> mojoDescriptors;
    
    /*
     * for the harness I think we have decided against going the route of using the maven project builder.
     * instead I think we are going to try and make an instance of the localrespository and assign that
     * to either the project stub or into the mojo directly with injection...not sure yet though.
     */
    //private MavenProjectBuilder projectBuilder;

    protected void setUp()
        throws Exception
    {
        assertTrue( "Maven 3.2.4 or better is required",
                    MAVEN_VERSION == null || new DefaultArtifactVersion( "3.2.3" ).compareTo( MAVEN_VERSION ) < 0 );

        configurator = getContainer().lookup( ComponentConfigurator.class, "basic" );

        InputStream is = getClass().getResourceAsStream( "/" + getPluginDescriptorLocation() );

        XmlStreamReader reader = new XmlStreamReader( is );

        InterpolationFilterReader interpolationFilterReader =
            new InterpolationFilterReader( new BufferedReader( reader ), container.getContext().getContextData() );

        PluginDescriptor pluginDescriptor = new PluginDescriptorBuilder().build( interpolationFilterReader );

        Artifact artifact =
            lookup( RepositorySystem.class ).createArtifact( pluginDescriptor.getGroupId(),
                                                             pluginDescriptor.getArtifactId(),
                                                             pluginDescriptor.getVersion(), ".jar" );

        artifact.setFile( getPluginArtifactFile() );
        pluginDescriptor.setPluginArtifact( artifact );
        pluginDescriptor.setArtifacts( Arrays.asList( artifact ) );

        for ( ComponentDescriptor<?> desc : pluginDescriptor.getComponents() )
        {
            getContainer().addComponentDescriptor( desc );
        }

        mojoDescriptors = new HashMap<String, MojoDescriptor>();
        for ( MojoDescriptor mojoDescriptor : pluginDescriptor.getMojos() )
        {
            mojoDescriptors.put( mojoDescriptor.getGoal(), mojoDescriptor );
        }
    }

    /**
     * Returns best-effort plugin artifact file.
     * <p>
     * First, attempts to determine parent directory of META-INF directory holding the plugin descriptor. If META-INF
     * parent directory cannot be determined, falls back to test basedir.
     */
    private File getPluginArtifactFile()
        throws IOException
    {
        final String pluginDescriptorLocation = getPluginDescriptorLocation();
        final URL resource = getClass().getResource( "/" + pluginDescriptorLocation );

        File file = null;

        // attempt to resolve relative to META-INF/maven/plugin.xml first
        if ( resource != null )
        {
            if ( "file".equalsIgnoreCase( resource.getProtocol() ) )
            {
                String path = resource.getPath();
                if ( path.endsWith( pluginDescriptorLocation ) )
                {
                    file = new File( path.substring( 0, path.length() - pluginDescriptorLocation.length() ) );
                }
            }
            else if ( "jar".equalsIgnoreCase( resource.getProtocol() ) )
            {
                // TODO is there a helper for this somewhere?
                try
                {
                    URL jarfile = new URL( resource.getPath() );
                    if ( "file".equalsIgnoreCase( jarfile.getProtocol() ) )
                    {
                        String path = jarfile.getPath();
                        if ( path.endsWith( pluginDescriptorLocation ) )
                        {
                            file =
                                new File( path.substring( 0, path.length() - pluginDescriptorLocation.length() - 2 ) );
                        }
                    }
                }
                catch ( MalformedURLException e )
                {
                    // not jar:file:/ URL, too bad
                }
            }
        }

        // fallback to test project basedir if couldn't resolve relative to META-INF/maven/plugin.xml
        if ( file == null || ! file.exists() )
        {
            file = new File( getBasedir() );
        }

        return file.getCanonicalFile();
    }

    protected InputStream getPublicDescriptorStream()
        throws Exception
    {
        return new FileInputStream( new File( getPluginDescriptorPath() ) );
    }

    protected String getPluginDescriptorPath()
    {
        return getBasedir() + "/target/classes/META-INF/maven/plugin.xml";
    }

    protected String getPluginDescriptorLocation()
    {
        return "META-INF/maven/plugin.xml";
    }

    protected void setupContainer()
    {
        ContainerConfiguration cc = setupContainerConfiguration();
        try
        {
            List<Module> modules = new ArrayList<Module>();
            addGuiceModules( modules );
            container = new DefaultPlexusContainer( cc, modules.toArray( new Module[modules.size()] ) );
        }
        catch ( PlexusContainerException e )
        {
            e.printStackTrace();
            fail( "Failed to create plexus container." );
        }   
    }

    /**
     * @since 3.0.0
     */
    protected void addGuiceModules( List<Module> modules )
    {
        // no custom guice modules by default
    }

    protected ContainerConfiguration setupContainerConfiguration()
    {
        ClassWorld classWorld = new ClassWorld( "plexus.core", Thread.currentThread().getContextClassLoader() );

        ContainerConfiguration cc = new DefaultContainerConfiguration()
          .setClassWorld( classWorld )
          .setClassPathScanning( PlexusConstants.SCANNING_INDEX )
          .setAutoWiring( true )
          .setName( "maven" );      

        return cc;
    }
    
    protected PlexusContainer getContainer()
    {
        if ( container == null )
        {
            setupContainer();
        }

        return container;
    }    
    
    /**
     * Lookup the mojo leveraging the subproject pom
     *
     * @param goal
     * @param pluginPom
     * @return a Mojo instance
     * @throws Exception
     */
    protected Mojo lookupMojo( String goal, String pluginPom )
        throws Exception
    {
        return lookupMojo( goal, new File( pluginPom ) );
    }

    /**
     * Lookup an empty mojo
     *
     * @param goal
     * @param pluginPom
     * @return a Mojo instance
     * @throws Exception
     */
    protected Mojo lookupEmptyMojo( String goal, String pluginPom )
        throws Exception
    {
        return lookupEmptyMojo( goal, new File( pluginPom ) );
    }

    /**
     * Lookup the mojo leveraging the actual subprojects pom
     *
     * @param goal
     * @param pom
     * @return a Mojo instance
     * @throws Exception
     */
    protected Mojo lookupMojo( String goal, File pom )
        throws Exception
    {
        File pluginPom = new File( getBasedir(), "pom.xml" );

        Xpp3Dom pluginPomDom = Xpp3DomBuilder.build( ReaderFactory.newXmlReader( pluginPom ) );

        String artifactId = pluginPomDom.getChild( "artifactId" ).getValue();

        String groupId = resolveFromRootThenParent( pluginPomDom, "groupId" );

        String version = resolveFromRootThenParent( pluginPomDom, "version" );

        PlexusConfiguration pluginConfiguration = extractPluginConfiguration( artifactId, pom );

        return lookupMojo( groupId, artifactId, version, goal, pluginConfiguration );
    }

    /**
     * Lookup the mojo leveraging the actual subprojects pom
     *
     * @param goal
     * @param pom
     * @return a Mojo instance
     * @throws Exception
     */
    protected Mojo lookupEmptyMojo( String goal, File pom )
        throws Exception
    {
        File pluginPom = new File( getBasedir(), "pom.xml" );

        Xpp3Dom pluginPomDom = Xpp3DomBuilder.build( ReaderFactory.newXmlReader( pluginPom ) );

        String artifactId = pluginPomDom.getChild( "artifactId" ).getValue();

        String groupId = resolveFromRootThenParent( pluginPomDom, "groupId" );

        String version = resolveFromRootThenParent( pluginPomDom, "version" );

        return lookupMojo( groupId, artifactId, version, goal, null );
    }

    /*
     protected Mojo lookupMojo( String groupId, String artifactId, String version, String goal, File pom )
     throws Exception
     {
     PlexusConfiguration pluginConfiguration = extractPluginConfiguration( artifactId, pom );

     return lookupMojo( groupId, artifactId, version, goal, pluginConfiguration );
     }
     */
    /**
     * lookup the mojo while we have all of the relavent information
     *
     * @param groupId
     * @param artifactId
     * @param version
     * @param goal
     * @param pluginConfiguration
     * @return a Mojo instance
     * @throws Exception
     */
    protected Mojo lookupMojo( String groupId, String artifactId, String version, String goal,
                               PlexusConfiguration pluginConfiguration )
        throws Exception
    {
        validateContainerStatus();

        // pluginkey = groupId : artifactId : version : goal

        Mojo mojo = (Mojo) lookup( Mojo.ROLE, groupId + ":" + artifactId + ":" + version + ":" + goal );

        LoggerManager loggerManager = (LoggerManager) getContainer().lookup( LoggerManager.class );
        
        Log mojoLogger = new DefaultLog( loggerManager.getLoggerForComponent( Mojo.ROLE ) );

        mojo.setLog( mojoLogger );

        if ( pluginConfiguration != null )
        {
            /* requires v10 of plexus container for lookup on expression evaluator
             ExpressionEvaluator evaluator = (ExpressionEvaluator) getContainer().lookup( ExpressionEvaluator.ROLE,
                                                                                         "stub-evaluator" );
             */
            ExpressionEvaluator evaluator = new ResolverExpressionEvaluatorStub();

            configurator.configureComponent( mojo, pluginConfiguration, evaluator, getContainer().getContainerRealm() );
        }

        return mojo;
    }

    /**
     * 
     * @param project
     * @param goal
     * @return
     * @throws Exception
     * @since 2.0
     */
    protected Mojo lookupConfiguredMojo( MavenProject project, String goal )
        throws Exception
    {
        return lookupConfiguredMojo( newMavenSession( project ), newMojoExecution( goal ) );
    }

    /**
     * 
     * @param session
     * @param execution
     * @return
     * @throws Exception
     * @throws ComponentConfigurationException
     * @since 2.0
     */
    protected Mojo lookupConfiguredMojo( MavenSession session, MojoExecution execution )
        throws Exception, ComponentConfigurationException
    {
        MavenProject project = session.getCurrentProject();
        MojoDescriptor mojoDescriptor = execution.getMojoDescriptor();

        Mojo mojo = (Mojo) lookup( mojoDescriptor.getRole(), mojoDescriptor.getRoleHint() );

        ExpressionEvaluator evaluator = new PluginParameterExpressionEvaluator( session, execution );

        Xpp3Dom configuration = null;
        Plugin plugin = project.getPlugin( mojoDescriptor.getPluginDescriptor().getPluginLookupKey() );
        if ( plugin != null )
        {
            configuration = (Xpp3Dom) plugin.getConfiguration();
        }
        if ( configuration == null )
        {
            configuration = new Xpp3Dom( "configuration" );
        }
        configuration = Xpp3Dom.mergeXpp3Dom( configuration, execution.getConfiguration() );

        PlexusConfiguration pluginConfiguration = new XmlPlexusConfiguration( configuration );

        if ( mojoDescriptor.getComponentConfigurator() != null )
        {
            configurator =
                getContainer().lookup( ComponentConfigurator.class, mojoDescriptor.getComponentConfigurator() );
        }        
        
        configurator.configureComponent( mojo, pluginConfiguration, evaluator, getContainer().getContainerRealm() );

        return mojo;
    }

    /**
     * 
     * @param project
     * @return
     * @since 2.0
     */
    protected MavenSession newMavenSession( MavenProject project )
    {
        MavenExecutionRequest request = new DefaultMavenExecutionRequest();
        MavenExecutionResult result = new DefaultMavenExecutionResult();

        MavenSession session = new MavenSession( container, MavenRepositorySystemUtils.newSession(), request, result );
        session.setCurrentProject( project );
        session.setProjects( Arrays.asList( project ) );
        return session;
    }

    /**
     * 
     * @param goal
     * @return
     * @since 2.0
     */
    protected MojoExecution newMojoExecution( String goal )
    {
        MojoDescriptor mojoDescriptor = mojoDescriptors.get( goal );
        assertNotNull( String.format( "The MojoDescriptor for the goal %s cannot be null.", goal ), mojoDescriptor );
        MojoExecution execution = new MojoExecution( mojoDescriptor );
        finalizeMojoConfiguration( execution );
        return execution;
    }

    // copy&paste from o.a.m.l.i.DefaultLifecycleExecutionPlanCalculator.finalizeMojoConfiguration(MojoExecution)
    private void finalizeMojoConfiguration( MojoExecution mojoExecution )
    {
        MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();

        Xpp3Dom executionConfiguration = mojoExecution.getConfiguration();
        if ( executionConfiguration == null )
        {
            executionConfiguration = new Xpp3Dom( "configuration" );
        }

        Xpp3Dom defaultConfiguration = MojoDescriptorCreator.convert( mojoDescriptor );

        Xpp3Dom finalConfiguration = new Xpp3Dom( "configuration" );

        if ( mojoDescriptor.getParameters() != null )
        {
            for ( Parameter parameter : mojoDescriptor.getParameters() )
            {
                Xpp3Dom parameterConfiguration = executionConfiguration.getChild( parameter.getName() );

                if ( parameterConfiguration == null )
                {
                    parameterConfiguration = executionConfiguration.getChild( parameter.getAlias() );
                }

                Xpp3Dom parameterDefaults = defaultConfiguration.getChild( parameter.getName() );

                parameterConfiguration =
                    Xpp3Dom.mergeXpp3Dom( parameterConfiguration, parameterDefaults, Boolean.TRUE );

                if ( parameterConfiguration != null )
                {
                    parameterConfiguration = new Xpp3Dom( parameterConfiguration, parameter.getName() );

                    if ( StringUtils.isEmpty( parameterConfiguration.getAttribute( "implementation" ) )
                        && StringUtils.isNotEmpty( parameter.getImplementation() ) )
                    {
                        parameterConfiguration.setAttribute( "implementation", parameter.getImplementation() );
                    }

                    finalConfiguration.addChild( parameterConfiguration );
                }
            }
        }

        mojoExecution.setConfiguration( finalConfiguration );
    }

    /**
     * @param artifactId
     * @param pom
     * @return the plexus configuration
     * @throws Exception
     */
    protected PlexusConfiguration extractPluginConfiguration( String artifactId, File pom )
        throws Exception
    {
        Reader reader = ReaderFactory.newXmlReader( pom );

        Xpp3Dom pomDom = Xpp3DomBuilder.build( reader );

        return extractPluginConfiguration( artifactId, pomDom );
    }

    /**
     * @param artifactId
     * @param pomDom
     * @return the plexus configuration
     * @throws Exception
     */
    protected PlexusConfiguration extractPluginConfiguration( String artifactId, Xpp3Dom pomDom )
        throws Exception
    {
        Xpp3Dom pluginConfigurationElement = null;

        Xpp3Dom buildElement = pomDom.getChild( "build" );
        if ( buildElement != null )
        {
            Xpp3Dom pluginsRootElement = buildElement.getChild( "plugins" );

            if ( pluginsRootElement != null )
            {
                Xpp3Dom[] pluginElements = pluginsRootElement.getChildren();

                for ( Xpp3Dom pluginElement : pluginElements )
                {
                    String pluginElementArtifactId = pluginElement.getChild( "artifactId" ).getValue();

                    if ( pluginElementArtifactId.equals( artifactId ) )
                    {
                        pluginConfigurationElement = pluginElement.getChild( "configuration" );

                        break;
                    }
                }

                if ( pluginConfigurationElement == null )
                {
                    throw new ConfigurationException( "Cannot find a configuration element for a plugin with an "
                        + "artifactId of " + artifactId + "." );
                }
            }
        }

        if ( pluginConfigurationElement == null )
        {
            throw new ConfigurationException( "Cannot find a configuration element for a plugin with an artifactId of "
                + artifactId + "." );
        }

        return new XmlPlexusConfiguration( pluginConfigurationElement );
    }

    /**
     * Configure the mojo
     *
     * @param mojo
     * @param artifactId
     * @param pom
     * @return a Mojo instance
     * @throws Exception
     */
    protected Mojo configureMojo( Mojo mojo, String artifactId, File pom )
        throws Exception
    {
        validateContainerStatus();

        PlexusConfiguration pluginConfiguration = extractPluginConfiguration( artifactId, pom );

        ExpressionEvaluator evaluator = new ResolverExpressionEvaluatorStub();

        configurator.configureComponent( mojo, pluginConfiguration, evaluator, getContainer().getContainerRealm() );

        return mojo;
    }

    /**
     * Configure the mojo with the given plexus configuration
     *
     * @param mojo
     * @param pluginConfiguration
     * @return a Mojo instance
     * @throws Exception
     */
    protected Mojo configureMojo( Mojo mojo, PlexusConfiguration pluginConfiguration )
        throws Exception
    {
        validateContainerStatus();

        ExpressionEvaluator evaluator = new ResolverExpressionEvaluatorStub();

        configurator.configureComponent( mojo, pluginConfiguration, evaluator, getContainer().getContainerRealm() );

        return mojo;
    }

    /**
     * Convenience method to obtain the value of a variable on a mojo that might not have a getter.
     *
     * NOTE: the caller is responsible for casting to to what the desired type is.
     *
     * @param object
     * @param variable
     * @return object value of variable
     * @throws IllegalArgumentException
     */
    protected Object getVariableValueFromObject( Object object, String variable )
        throws IllegalAccessException
    {
        Field field = ReflectionUtils.getFieldByNameIncludingSuperclasses( variable, object.getClass() );

        field.setAccessible( true );

        return field.get( object );
    }

    /**
     * Convenience method to obtain all variables and values from the mojo (including its superclasses)
     *
     * Note: the values in the map are of type Object so the caller is responsible for casting to desired types.
     *
     * @param object
     * @return map of variable names and values
     */
    protected Map<String, Object> getVariablesAndValuesFromObject( Object object )
        throws IllegalAccessException
    {
        return getVariablesAndValuesFromObject( object.getClass(), object );
    }

    /**
     * Convenience method to obtain all variables and values from the mojo (including its superclasses)
     *
     * Note: the values in the map are of type Object so the caller is responsible for casting to desired types.
     *
     * @param clazz
     * @param object
     * @return map of variable names and values
     */
    protected Map<String, Object> getVariablesAndValuesFromObject( Class<?> clazz, Object object )
        throws IllegalAccessException
    {
        Map<String, Object> map = new HashMap<String, Object>();

        Field[] fields = clazz.getDeclaredFields();

        AccessibleObject.setAccessible( fields, true );

        for ( Field field : fields )
        {
            map.put( field.getName(), field.get( object ) );
        }

        Class<?> superclass = clazz.getSuperclass();

        if ( !Object.class.equals( superclass ) )
        {
            map.putAll( getVariablesAndValuesFromObject( superclass, object ) );
        }

        return map;
    }

    /**
     * Convenience method to set values to variables in objects that don't have setters
     *
     * @param object
     * @param variable
     * @param value
     * @throws IllegalAccessException
     */
    protected void setVariableValueToObject( Object object, String variable, Object value )
        throws IllegalAccessException
    {
        Field field = ReflectionUtils.getFieldByNameIncludingSuperclasses( variable, object.getClass() );

        field.setAccessible( true );

        field.set( object, value );
    }

    /**
     * sometimes the parent element might contain the correct value so generalize that access
     *
     * TODO find out where this is probably done elsewhere
     *
     * @param pluginPomDom
     * @param element
     * @return
     * @throws Exception
     */
    private String resolveFromRootThenParent( Xpp3Dom pluginPomDom, String element )
        throws Exception
    {
        Xpp3Dom elementDom = pluginPomDom.getChild( element );

        // parent might have the group Id so resolve it
        if ( elementDom == null )
        {
            Xpp3Dom pluginParentDom = pluginPomDom.getChild( "parent" );

            if ( pluginParentDom != null )
            {
                elementDom = pluginParentDom.getChild( element );

                if ( elementDom == null )
                {
                    throw new Exception( "unable to determine " + element );
                }

                return elementDom.getValue();
            }

            throw new Exception( "unable to determine " + element );
        }

        return elementDom.getValue();
    }

    /**
     * We should make sure this is called in each method that makes use of the container,
     * otherwise we throw ugly NPE's
     *
     * crops up when the subclassing code defines the setUp method but doesn't call super.setUp()
     *
     * @throws Exception
     */
    private void validateContainerStatus()
        throws Exception
    {
        if ( getContainer() != null )
        {
            return;
        }

        throw new Exception( "container is null, make sure super.setUp() is called" );
    }    
}
