VProjectItem* VProjectItemFolder::Instantiate( const XBOX::VURL& inURL, VProjectItem *inParent, bool inExternalReference)
{
	VProjectItem *result = NULL;

	VFilePath path;
	if (inURL.GetFilePath( path))
	{
		if (path.IsFolder())
		{
			VString folderName;
			path.GetFolderName( folderName);

			VProjectItemFolder *behaviour = new VProjectItemFolder( NULL);
			if (behaviour != NULL)
			{
				result = new VProjectItem( behaviour);
				if (result != NULL)
				{
					result->SetURL( inURL);
					result->SetName( folderName);
					result->SetDisplayName( folderName);
					result->SetExternalReference( inExternalReference);

					if (inParent != NULL)
						inParent->AttachChild( result);
				}
			}
		}
	}
	return result;
}
static bool _BuildExecutablePath( const VFilePath &inPath, VFilePath& outExecutablePath)
{
	bool ok;
	if (inPath.IsFile())
	{
		outExecutablePath = inPath;
		ok = true;
	}
	else if (inPath.IsFolder())
	{
		// if path is a folder named truc.someextension,
		// look at truc.someextension\Contents\Windows\truc.dll
		
		// afabre : finally, we look the dll near the exe file
		VString name;
		inPath.GetName( name);
		outExecutablePath = inPath;
		outExecutablePath = outExecutablePath.ToParent().ToParent();
		outExecutablePath.SetFileName( name);
		outExecutablePath.SetExtension( CVSTR( "dll"));
		ok = true;
	}
	else
	{
		ok = false;
	}

	return ok;
}
VFolder* VRIAServerSolution::RetainFolder() const
{
	VFolder *folder = NULL;

	if (fDesignSolution != NULL)
	{
		VProjectItem *item = fDesignSolution->GetSolutionFileProjectItem();
		if (item != NULL)
		{
			VFilePath path;
			item->GetFilePath( path);
			path = path.ToFolder();
			if (path.IsFolder())
			{
				folder = new VFolder( path);
				if (folder != NULL && !folder->Exists())
				{
					folder->Release();
					folder = NULL;
				}
			}
		}
	}	
	return folder;
}
VFolder* VProjectItemFolder::RetainFolder() const
{
	VFolder *folder = NULL;

	if (fOwner != NULL)
	{
		VFilePath path;
		if (fOwner->GetFilePath( path) && path.IsFolder())
			folder = new VFolder( path);
	}
	return folder;
}
/*
	static
*/
VError VFolder::ResolveAliasFolder( VFolder **ioFolder, bool inDeleteInvalidAlias)
{
	VError err = VE_OK;
	if ( (*ioFolder != NULL) && (*ioFolder)->fPath.IsFolder() && !(*ioFolder)->fFolder.Exists( false /* doesn't check alias */) )
	{
		// the folder doesn't exists
		// maybe is it an alias file?
		VString path = (*ioFolder)->fPath.GetPath();
		if (testAssert( path[path.GetLength()-1] == FOLDER_SEPARATOR))
		{
			path.Truncate( path.GetLength()-1);
			#if VERSIONWIN
			path += ".lnk";
			#endif
			VFile file( path);
			if (file.IsAliasFile() && file.Exists())
			{
				VFilePath resolvedPath;
				err = file.GetImpl()->ResolveAlias( resolvedPath);	// nothrow
				if (err == VE_OK)
				{
					if (resolvedPath.IsFolder())
					{
						(*ioFolder)->Release();
						*ioFolder = new VFolder( resolvedPath);
					}
					else if (inDeleteInvalidAlias)
					{
						err = file.Delete();
					}
					else
					{
						StThrowFileError errThrow( *ioFolder, VE_FILE_CANNOT_RESOLVE_ALIAS_TO_FOLDER);
						err = errThrow.GetError();
					}
				}
				else if (inDeleteInvalidAlias)
				{
					err = file.Delete();
				}
				else
				{
					if (IS_NATIVE_VERROR( err))
					{
						StThrowFileError errThrow( &file, VE_FILE_CANNOT_RESOLVE_ALIAS, err);
						err = errThrow.GetError();
					}
				}
			}
		}
	}
	return err;
}
VFolder *XWinFolderIterator::_GetPath( const VString& inFileName, DWORD inAttributes)
{
	VFolder *path = NULL;
	if (inFileName[0] != CHAR_FULL_STOP)
	{
		bool isInvisible = (inAttributes & FILE_ATTRIBUTE_HIDDEN) ? true : false;
		bool isFolder = (inAttributes & FILE_ATTRIBUTE_DIRECTORY) ? true : false;
		if (!isInvisible || (fOptions & FI_WANT_INVISIBLES))
		{
			if (isFolder)
			{
				if (fOptions & FI_WANT_FOLDERS)
				{
					VFilePath currentPath;
					currentPath.FromFilePath( fRootPath);
					currentPath.ToSubFolder( inFileName);
					path = new VFolder(currentPath);
				}
			}
			else
			{
				// it's a file, maybe it's an alias to a folder
				if (fOptions & FI_RESOLVE_ALIASES)
				{
					VFilePath currentPath;
					currentPath.FromFilePath( fRootPath);
					currentPath.SetFileName( inFileName);
					VFile theFile( currentPath);
					if (theFile.IsAliasFile())
					{
						VFilePath resolvedPath;
						if ( (theFile.ResolveAlias( resolvedPath) == VE_OK) && resolvedPath.IsFolder())
							path = new VFolder( resolvedPath);
					}
				}
			}
		}
	}
	return path;
}
VFolder *VProcess::RetainProductSystemFolder( ESystemFolderKind inSelector, bool inCreateFolderIfNotFound) const
{
	VFolder *folder = NULL;
	
	bool allUsers;
	bool useProductSubFolder;
	ESystemFolderKind currentUserFolder;
	switch( inSelector)
	{
		case eFK_UserDocuments:
		case eFK_Temporary:
			allUsers = true;
			useProductSubFolder = true;
			break;

		case eFK_CommonPreferences:
			currentUserFolder = eFK_UserPreferences;
			allUsers = true;
			useProductSubFolder = true;
			break;

		case eFK_CommonApplicationData:
			currentUserFolder = eFK_UserApplicationData;
			allUsers = true;
			useProductSubFolder = true;
			break;

		case eFK_CommonCache:
			currentUserFolder = eFK_UserCache;
			allUsers = true;
			useProductSubFolder = true;
			break;

		case eFK_UserPreferences:
		case eFK_UserApplicationData:
		case eFK_UserCache:
			allUsers = false;
			useProductSubFolder = true;
			break;
		
		default:
			allUsers = false;
			useProductSubFolder = false;
			break;
	}
	
	if (useProductSubFolder)
	{
		VFolder *parent = VFolder::RetainSystemFolder( inSelector, inCreateFolderIfNotFound);
		if (parent != NULL)
		{
			VError err;
			VString folderName;
			GetProductName( folderName);

			// accepte un alias
			VString aliasName( folderName);
			#if VERSIONWIN
			aliasName += ".lnk";
			#endif
			VFile aliasFile( *parent, aliasName);
			if (aliasFile.Exists() && aliasFile.IsAliasFile())
			{
				VFilePath target;
				err = aliasFile.ResolveAlias( target);
				if ( (err == VE_OK) && target.IsFolder() )
				{
					folder = new VFolder( target);
				}
			}

			if (folder == NULL)
			{
				folder = new VFolder( *parent, folderName);
			}
			
			if (!folder->Exists())
			{
				if (inCreateFolderIfNotFound)
				{
					if (allUsers)
					{
						// drop errors if we can retry in current user home directory
						StErrorContextInstaller context( false);
						err = folder->CreateRecursive( allUsers);
					}
					else
					{
						err = folder->CreateRecursive( allUsers);
					}
					if (err != VE_OK)
					{
						ReleaseRefCountable( &folder);
						
						// si on nous a demande de creer dans "all users", on ressaie dans le dossier de l'utilisateur courant
						if (allUsers)
						{
							folder = RetainProductSystemFolder( currentUserFolder, inCreateFolderIfNotFound);
						}
					}
				}
				else
				{
					ReleaseRefCountable( &folder);
				}
			}
		}

		ReleaseRefCountable( &parent);
	}
	else
	{
		folder = VFolder::RetainSystemFolder( inSelector, inCreateFolderIfNotFound);
	}

	return folder;
}