Index: wagon-providers/wagon-scm/src/test/java/org/apache/maven/wagon/providers/scm/ScmSvnExeWagonTest.java
===================================================================
--- wagon-providers/wagon-scm/src/test/java/org/apache/maven/wagon/providers/scm/ScmSvnExeWagonTest.java	(revision 957839)
+++ wagon-providers/wagon-scm/src/test/java/org/apache/maven/wagon/providers/scm/ScmSvnExeWagonTest.java	(working copy)
@@ -19,8 +19,14 @@
  * under the License.
  */
 
+import java.io.File;
+import java.io.IOException;
+
 import org.apache.maven.scm.provider.ScmProvider;
 import org.apache.maven.scm.provider.svn.svnexe.SvnExeScmProvider;
+import org.apache.maven.wagon.FileTestUtils;
+import org.apache.maven.wagon.Wagon;
+import org.codehaus.plexus.util.FileUtils;
 
 /**
  * Test for ScmWagon using SVN Exe as underlying SCM
@@ -37,4 +43,113 @@
         return new SvnExeScmProvider();
     }
 
+    public void testPutFileBasedirDoesNotExistSingleLevel()
+        throws Exception
+    {
+        setupRepositories();
+
+        setupWagonTestingFixtures();
+
+        Wagon wagon = (ScmWagon) getWagon();
+
+        sourceFile = new File( FileTestUtils.getTestOutputDir(), "directory-copy" );
+
+        sourceFile.mkdirs();
+
+        writeTestFile( "test-resource-1.txt" );
+
+        testRepository.setUrl( getTestRepositoryUrl() + "/docs/" );
+
+        wagon.connect( testRepository, getAuthInfo() );
+
+        wagon.put( new File( sourceFile, "test-resource-1.txt" ), "directory-copy/test-resource-1.txt" );
+
+        wagon.put( new File( sourceFile, "test-resource-1.txt" ), "directory-copy/second-level-dir/test-resource-1.txt" );
+
+        destFile = FileTestUtils.createUniqueFile( getName(), getName() );
+
+        destFile.deleteOnExit();
+
+        wagon.get( "directory-copy/test-resource-1.txt", destFile );
+
+        wagon.get( "directory-copy/second-level-dir/test-resource-1.txt", destFile );
+
+        wagon.disconnect();
+
+        tearDownWagonTestingFixtures();
+    }
+
+    public void testPutFileBasedirDoesNotExistMultipleLevels()
+        throws Exception
+    {
+        setupRepositories();
+
+        setupWagonTestingFixtures();
+
+        Wagon wagon = (ScmWagon) getWagon();
+
+        sourceFile = new File( FileTestUtils.getTestOutputDir(), "directory-copy" );
+
+        sourceFile.mkdirs();
+
+        writeTestFile( "test-resource-1.txt" );
+
+        testRepository.setUrl( getTestRepositoryUrl() + "/docs/1.0-SNAPSHOT/" );
+
+        wagon.connect( testRepository, getAuthInfo() );
+
+        wagon.put( new File( sourceFile, "test-resource-1.txt" ), "directory-copy/test-resource-1.txt" );
+
+        wagon.put( new File( sourceFile, "test-resource-1.txt" ), "directory-copy/second-level-dir/test-resource-1.txt" );
+
+        destFile = FileTestUtils.createUniqueFile( getName(), getName() );
+
+        destFile.deleteOnExit();
+
+        wagon.get( "directory-copy/test-resource-1.txt", destFile );
+
+        wagon.get( "directory-copy/second-level-dir/test-resource-1.txt", destFile );
+
+        wagon.disconnect();
+
+        tearDownWagonTestingFixtures();
+    }
+
+    public void testPutFileBasedirExists()
+        throws Exception
+    {
+        setupRepositories();
+
+        setupWagonTestingFixtures();
+
+        Wagon wagon = (ScmWagon) getWagon();
+
+        sourceFile = FileTestUtils.getTestOutputDir();
+
+        sourceFile.mkdirs();
+
+        writeTestFile( "test-resource-1.txt" );
+
+        wagon.connect( testRepository, getAuthInfo() );
+
+        wagon.put( new File( sourceFile, "test-resource-1.txt" ), "test-resource-1.txt" );
+
+        destFile = FileTestUtils.createUniqueFile( getName(), getName() );
+
+        destFile.deleteOnExit();
+
+        wagon.get( "test-resource-1.txt", destFile );
+
+        wagon.disconnect();
+
+        tearDownWagonTestingFixtures();
+    }
+
+    private void writeTestFile( String child )
+        throws IOException
+    {
+        File dir = new File( sourceFile, child );
+        dir.getParentFile().mkdirs();
+        FileUtils.fileWrite( dir.getAbsolutePath(), child );
+    }
 }
Index: wagon-providers/wagon-scm/src/main/java/org/apache/maven/wagon/providers/scm/ScmWagon.java
===================================================================
--- wagon-providers/wagon-scm/src/main/java/org/apache/maven/wagon/providers/scm/ScmWagon.java	(revision 957839)
+++ wagon-providers/wagon-scm/src/main/java/org/apache/maven/wagon/providers/scm/ScmWagon.java	(working copy)
@@ -27,6 +27,7 @@
 import org.apache.maven.scm.command.add.AddScmResult;
 import org.apache.maven.scm.command.checkout.CheckOutScmResult;
 import org.apache.maven.scm.command.list.ListScmResult;
+import org.apache.maven.scm.command.mkdir.MkdirScmResult;
 import org.apache.maven.scm.manager.NoSuchScmProviderException;
 import org.apache.maven.scm.manager.ScmManager;
 import org.apache.maven.scm.provider.ScmProvider;
@@ -79,7 +80,9 @@
     private ScmManager scmManager;
 
     private File checkoutDirectory;
-
+        
+    private static final File TMP_DIR = new File( System.getProperty( "java.io.tmpdir" ) );
+    
     /**
      * Get the {@link ScmManager} used in this Wagon
      *
@@ -148,8 +151,6 @@
         {
             removeCheckoutDirectory();
         }
-
-        checkoutDirectory.mkdirs();
     }
 
     private File createCheckoutDirectory()
@@ -173,10 +174,9 @@
         return checkoutDirectory;
     }
 
-
     private void removeCheckoutDirectory()
         throws ConnectionException
-    {
+    {   
         if( checkoutDirectory == null )
         {
             return; // Silently return.
@@ -252,31 +252,36 @@
         if ( source.isDirectory() )
         {
             throw new IllegalArgumentException( "Source is a directory: " + source );
-        }
+        }        
+        
         putInternal( source, targetName );
     }
-
+    
     /**
      * Puts both files and directories
      *
      * @param source
      * @param targetName
      * @throws TransferFailedException
+     * @throws ResourceDoesNotExistException 
+     * @throws AuthorizationException 
      */
     private void putInternal( File source, String targetName )
-        throws TransferFailedException
+        throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
     {
         Resource target = new Resource( targetName );
 
         firePutInitiated( target, source );
 
+        String repoUrl = new String( getRepository().getUrl() );
+
         try
         {
             ScmRepository scmRepository = getScmRepository( getRepository().getUrl() );
 
             target.setContentLength( source.length() );
             target.setLastModified( source.lastModified() );
-            
+
             firePutStarted( target, source );
 
             String msg = "Wagon: Adding " + source.getName() + " to repository";
@@ -284,13 +289,41 @@
             ScmProvider scmProvider = getScmProvider( scmRepository.getProvider() );
 
             String checkoutTargetName = source.isDirectory() ? targetName : getDirname( targetName );
-            String relPath = checkOut( scmProvider, scmRepository, checkoutTargetName, target );
 
+            String relPath = "";
+            String missingDirs = "";
+            String baseRepoUrl = getBaseRepoUrl( repoUrl, repoUrl );
+
+            if ( repoUrl.equals( baseRepoUrl ) )
+            {
+                // path exists
+                relPath = checkOut( scmProvider, scmRepository, checkoutTargetName, target );
+            }
+            else
+            {
+                // path does not exist
+                ScmRepository baseScmRepository = getScmRepository( baseRepoUrl );
+
+                missingDirs = StringUtils.difference( baseRepoUrl, repoUrl );
+
+                fireSessionDebug( "Missing directory paths in target repo: " + missingDirs );
+
+                // create the missing directories in the target repo using the mkdir command
+                boolean success = createMissingDirectories( scmProvider, missingDirs, baseScmRepository );
+
+                if ( success )
+                {
+                    relPath = checkOut( scmProvider, scmRepository, checkoutTargetName, target );
+                }
+                else
+                {
+                    throw new ResourceDoesNotExistException( "Path does not exist!" );
+                }
+            }           
+
             File newCheckoutDirectory = new File( checkoutDirectory, relPath );
+            File scmFile = new File( newCheckoutDirectory, source.isDirectory() ? "" : getFilename( targetName ) );
 
-            File scmFile =
-                new File( newCheckoutDirectory, source.isDirectory() ? "" : getFilename( targetName ) );
-
             boolean fileAlreadyInScm = scmFile.exists();
 
             if ( !scmFile.equals( source ) )
@@ -307,31 +340,32 @@
 
             if ( !fileAlreadyInScm || scmFile.isDirectory() )
             {
-                int addedFiles = addFiles( scmProvider, scmRepository, newCheckoutDirectory,
-                                           source.isDirectory() ? "" : scmFile.getName() );
+                int addedFiles =
+                    addFiles( scmProvider, scmRepository, newCheckoutDirectory, source.isDirectory() ? ""
+                                    : scmFile.getName() );
 
                 if ( !fileAlreadyInScm && addedFiles == 0 )
                 {
-                    throw new ScmException(
-                        "Unable to add file to SCM: " + scmFile + "; see error messages above for more information" );
+                    throw new ScmException( "Unable to add file to SCM: " + scmFile +
+                        "; see error messages above for more information" );
                 }
             }
 
-            ScmResult result = scmProvider.checkIn( scmRepository, new ScmFileSet( checkoutDirectory ),
-                                                    (ScmVersion) null, msg );
+            ScmResult result =
+                scmProvider.checkIn( scmRepository, new ScmFileSet( checkoutDirectory ), (ScmVersion) null, msg );
 
             checkScmResult( result );
         }
         catch ( ScmException e )
         {
             fireTransferError( target, e, TransferEvent.REQUEST_GET );
-            
+
             throw new TransferFailedException( "Error interacting with SCM: " + e.getMessage(), e );
         }
         catch ( IOException e )
         {
             fireTransferError( target, e, TransferEvent.REQUEST_GET );
-            
+
             throw new TransferFailedException( "Error interacting with SCM: " + e.getMessage(), e );
         }
 
@@ -344,6 +378,118 @@
     }
 
     /**
+     * Executes the SCM mkdir command for each missing directory, based on the 'missingDirs' path.
+     *  
+     * @param scmProvider
+     * @param missingDirs
+     * @param baseScmRepository
+     * @return
+     * @throws ScmException
+     */
+    private boolean createMissingDirectories( ScmProvider scmProvider, String missingDirs,
+                                              ScmRepository baseScmRepository )
+        throws ScmException
+    {
+        String[] missingDirsSegments = StringUtils.split( missingDirs, "/" );
+        List missingDirPaths = new ArrayList();
+        String path = "";
+        for ( int i = 0; i < missingDirsSegments.length; i++ )
+        {
+            String dir = missingDirsSegments[i];
+            path = path + ( StringUtils.isEmpty( path ) ? "" : "/" ) + dir;
+            missingDirPaths.add( path );
+        }
+
+        boolean success = true;
+        for ( Iterator it = missingDirPaths.iterator(); it.hasNext(); )
+        {
+            String dir = (String) it.next();
+
+            fireSessionDebug( "Creating missing dir '" + dir + "' in target repository." );
+
+            ScmFileSet fileSet = new ScmFileSet( TMP_DIR, new File( dir ) );
+            MkdirScmResult result = scmProvider.mkdir( baseScmRepository, fileSet, "create missing directories", false );
+
+            if ( !result.isSuccess() )
+            {
+                success = false;
+                break;
+            }
+        }
+        return success;
+    }
+    
+    /**
+     * Gets the base URL/path that is existing in the original repository url
+     * 
+     * @param repoUrl
+     * @param originalRepoUrl
+     * @return
+     * @throws NoSuchScmProviderException
+     * @throws ScmRepositoryException
+     * @throws AuthorizationException
+     * @throws TransferFailedException
+     */
+    private String getBaseRepoUrl( String repoUrl, String originalRepoUrl )
+        throws NoSuchScmProviderException, ScmRepositoryException, AuthorizationException, TransferFailedException
+    {
+        if ( resourceExists( "/", repoUrl ) )
+        {
+            return ( repoUrl );
+        }
+        else
+        {
+            String chomped = getChompedUrl( repoUrl );
+
+            return getBaseRepoUrl( chomped, originalRepoUrl );
+        }
+    }
+    
+    /**
+     * Checks if the specified resource exists in the specified repository url.
+     * 
+     * @param resourceName
+     * @param repositoryUrl
+     * @return
+     * @throws TransferFailedException
+     * @throws AuthorizationException
+     */
+    private boolean resourceExists( String resourceName, String repositoryUrl )
+        throws TransferFailedException, AuthorizationException
+    {
+        try
+        {
+            getFileList( resourceName, repositoryUrl );
+
+            return true;
+        }
+        catch ( ResourceDoesNotExistException e )
+        {
+            return false;
+        }
+    }
+    
+    /**
+     * Removes the last directory in the path. If the given url does not end with "/", it removes the directory name
+     * after the last "/".
+     * 
+     * @param repoUrl
+     * @return
+     */
+    private String getChompedUrl( String repoUrl )
+    {
+        if ( repoUrl.endsWith( "/" ) )
+        {
+            String chomped = StringUtils.chompLast( repoUrl, "/" );
+            return getChompedUrl( chomped );
+        }
+        else
+        {
+            return StringUtils.chomp( repoUrl, "/" );
+        }
+    }
+
+    /**
      * Returns the relative path to targetName in the checkout dir. If the targetName already exists in the scm, this
      * will be the empty string.
      *
@@ -356,9 +502,9 @@
     private String checkOut( ScmProvider scmProvider, ScmRepository scmRepository, String targetName,
                              Resource resource )
         throws TransferFailedException
-    {
+    {   
         checkoutDirectory = createCheckoutDirectory();
-
+        
         Stack stack = new Stack();
 
         String target = targetName;
@@ -401,7 +547,7 @@
             checkScmResult( ret );
         }
         catch ( ScmException e )
-        {
+        {   
             fireTransferError( resource, e, TransferEvent.REQUEST_PUT );
             
             throw new TransferFailedException( "Error checking out: " + e.getMessage(), e );
@@ -456,7 +602,7 @@
         int addedFiles = 0;
 
         File scmFile = new File( basedir, scmFilePath );
-
+        
         if ( scmFilePath.length() != 0 )
         {
             AddScmResult result = scmProvider.add( scmRepository, new ScmFileSet( basedir, new File( scmFilePath ) ) );
@@ -590,7 +736,7 @@
 
                 scmProvider.checkOut( scmRepository, new ScmFileSet( basedir ), (ScmVersion) null );
             }
-
+            
             if ( !scmFile.exists() )
             {
                 throw new ResourceDoesNotExistException( "Unable to find resource " + destination + " after checkout" );
@@ -626,9 +772,15 @@
     public List getFileList( String resourcePath )
         throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
     {
+        return getFileList( resourcePath, getRepository().getUrl() );
+    }
+    
+    private List getFileList( String resourcePath, String repositoryUrl ) 
+        throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
+    {
         try
         {
-            ScmRepository repository = getScmRepository( getRepository().getUrl() );
+            ScmRepository repository = getScmRepository( repositoryUrl );
 
             ScmProvider provider = getScmProvider( repository.getProvider() );
 
@@ -665,7 +817,7 @@
         try
         {
             getFileList( resourceName );
-
+            
             return true;
         }
         catch ( ResourceDoesNotExistException e )
Index: wagon-providers/wagon-scm/pom.xml
===================================================================
--- wagon-providers/wagon-scm/pom.xml	(revision 957839)
+++ wagon-providers/wagon-scm/pom.xml	(working copy)
@@ -37,32 +37,37 @@
     <dependency>
       <groupId>org.apache.maven.scm</groupId>
       <artifactId>maven-scm-api</artifactId>
-      <version>1.0</version>
+      <version>1.4-SNAPSHOT</version>
     </dependency>
     <dependency>
+      <groupId>org.codehaus.plexus</groupId>
+      <artifactId>plexus-utils</artifactId>
+      <version>1.5.6</version>
+    </dependency>    
+    <dependency>
       <groupId>org.apache.maven.scm</groupId>
       <artifactId>maven-scm-manager-plexus</artifactId>
-      <version>1.0</version>
+      <version>1.4-SNAPSHOT</version>
       <scope>runtime</scope>
     </dependency>
     <dependency>
       <groupId>org.apache.maven.scm</groupId>
       <artifactId>maven-scm-test</artifactId>
-      <version>1.0</version>
+      <version>1.4-SNAPSHOT</version>
       <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.apache.maven.scm</groupId>
       <artifactId>maven-scm-provider-cvsexe</artifactId>
-      <version>1.0</version>
+      <version>1.4-SNAPSHOT</version>
       <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.apache.maven.scm</groupId>
       <artifactId>maven-scm-provider-svnexe</artifactId>
-      <version>1.0</version>
+      <version>1.4-SNAPSHOT</version>
       <scope>test</scope>
-    </dependency>
+    </dependency>    
   </dependencies>
 
   <build>

