/**************************************************************
 *
 * 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.
 *
 *************************************************************/

package complex.storages;

import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XInterface;
import com.sun.star.uno.AnyConverter;

import com.sun.star.lang.*;
import com.sun.star.embed.*;
import com.sun.star.packages.*;
import com.sun.star.io.*;
import com.sun.star.beans.*;

import share.LogWriter;

public class TestHelper  {

	LogWriter m_aLogWriter;
	String m_sTestPrefix;

	public TestHelper( LogWriter aLogWriter, String sTestPrefix )
	{
		m_aLogWriter = aLogWriter;
		m_sTestPrefix = sTestPrefix;
	}

	public boolean WriteBytesToStream( XStream xStream,
										String sStreamName,
										String sMediaType,
										boolean bCompressed,
										byte[] pBytes )
	{
		// get output stream of substream
		XOutputStream xOutput = xStream.getOutputStream();
		if ( xOutput == null )
		{
			Error( "Can't get XOutputStream implementation from substream '" + sStreamName + "'!" );
			return false;
		}

		// get XTrucate implementation from output stream
		XTruncate xTruncate = (XTruncate) UnoRuntime.queryInterface( XTruncate.class, xOutput );
		if ( xTruncate == null )
		{
			Error( "Can't get XTruncate implementation from substream '" + sStreamName + "'!" );
			return false;
		}

		// write requested byte sequence
		try
		{
			xTruncate.truncate();
			xOutput.writeBytes( pBytes );
		}
		catch( Exception e )
		{
			Error( "Can't write to stream '" + sStreamName + "', exception: " + e );
			return false;
		}

		// get access to the XPropertySet interface
		XPropertySet xPropSet = (XPropertySet) UnoRuntime.queryInterface( XPropertySet.class, xStream );
		if ( xPropSet == null )
		{
			Error( "Can't get XPropertySet implementation from substream '" + sStreamName + "'!" );
			return false;
		}

		// set properties to the stream
		try
		{
			xPropSet.setPropertyValue( "MediaType", sMediaType );
			xPropSet.setPropertyValue( "Compressed", new Boolean( bCompressed ) );
		}
		catch( Exception e )
		{
			Error( "Can't set properties to substream '" + sStreamName + "', exception: " + e );
			return false;
		}

		// check size property of the stream
		try
		{
			int nSize = AnyConverter.toInt( xPropSet.getPropertyValue( "Size" ) );
			if ( nSize != pBytes.length )
			{
				Error( "The 'Size' property of substream '" + sStreamName + "' contains wrong value!" );
				return false;
			}
		}
		catch( Exception e )
		{
			Error( "Can't get 'Size' property from substream '" + sStreamName + "', exception: " + e );
			return false;
		}

		return true;
	}

	public boolean WriteBytesToSubstreamDefaultCompressed( XStorage xStorage,
										                    String sStreamName,
										                    String sMediaType,
										                    byte[] pBytes )
	{
		// open substream element
		XStream xSubStream = null;
		try
		{
			Object oSubStream = xStorage.openStreamElement( sStreamName, ElementModes.WRITE );
			xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
			if ( xSubStream == null )
			{
				Error( "Can't create substream '" + sStreamName + "'!" );
				return false;
			}
		}
		catch( Exception e )
		{
			Error( "Can't create substream '" + sStreamName + "', exception : " + e + "!" );
			return false;
		}

		// get output stream of substream
		XOutputStream xOutput = xSubStream.getOutputStream();
		if ( xOutput == null )
		{
			Error( "Can't get XOutputStream implementation from substream '" + sStreamName + "'!" );
			return false;
		}

		// get XTrucate implementation from output stream
		XTruncate xTruncate = (XTruncate) UnoRuntime.queryInterface( XTruncate.class, xOutput );
		if ( xTruncate == null )
		{
			Error( "Can't get XTruncate implementation from substream '" + sStreamName + "'!" );
			return false;
		}

		// write requested byte sequence
		try
		{
			xTruncate.truncate();
			xOutput.writeBytes( pBytes );
		}
		catch( Exception e )
		{
			Error( "Can't write to stream '" + sStreamName + "', exception: " + e );
			return false;
		}

		// get access to the XPropertySet interface
		XPropertySet xPropSet = (XPropertySet) UnoRuntime.queryInterface( XPropertySet.class, xSubStream );
		if ( xPropSet == null )
		{
			Error( "Can't get XPropertySet implementation from substream '" + sStreamName + "'!" );
			return false;
		}

		// set properties to the stream
        // do not set the compressed property
		try
		{
			xPropSet.setPropertyValue( "MediaType", sMediaType );
		}
		catch( Exception e )
		{
			Error( "Can't set properties to substream '" + sStreamName + "', exception: " + e );
			return false;
		}

		// check size property of the stream
		try
		{
			int nSize = AnyConverter.toInt( xPropSet.getPropertyValue( "Size" ) );
			if ( nSize != pBytes.length )
			{
				Error( "The 'Size' property of substream '" + sStreamName + "' contains wrong value!" );
				return false;
			}
		}
		catch( Exception e )
		{
			Error( "Can't get 'Size' property from substream '" + sStreamName + "', exception: " + e );
			return false;
		}

		// free the stream resources, garbage collector may remove the object too late
		if ( !disposeStream( xSubStream, sStreamName ) )
			return false;

		return true;
	}

	public boolean WriteBytesToSubstream( XStorage xStorage,
										  String sStreamName,
										  String sMediaType,
										  boolean bCompressed,
										  byte[] pBytes )
	{
		// open substream element
		XStream xSubStream = null;
		try
		{
			Object oSubStream = xStorage.openStreamElement( sStreamName, ElementModes.WRITE );
			xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
			if ( xSubStream == null )
			{
				Error( "Can't create substream '" + sStreamName + "'!" );
				return false;
			}
		}
		catch( Exception e )
		{
			Error( "Can't create substream '" + sStreamName + "', exception : " + e + "!" );
			return false;
		}

		if ( !WriteBytesToStream( xSubStream, sStreamName, sMediaType, bCompressed, pBytes ) )
			return false;

		// free the stream resources, garbage collector may remove the object too late
		if ( !disposeStream( xSubStream, sStreamName ) )
			return false;

		return true;
	}

	public boolean WriteBytesToEncrSubstream( XStorage xStorage,
											  String sStreamName,
											  String sMediaType,
											  boolean bCompressed,
											  byte[] pBytes,
											  String sPass )
	{
		// open substream element
		XStream xSubStream = null;
		try
		{
			Object oSubStream = xStorage.openEncryptedStreamElement( sStreamName, ElementModes.WRITE, sPass );
			xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
			if ( xSubStream == null )
			{
				Error( "Can't create substream '" + sStreamName + "'!" );
				return false;
			}
		}
		catch( Exception e )
		{
			Error( "Can't create substream '" + sStreamName + "', exception : " + e + "!" );
			return false;
		}

		if ( !WriteBytesToStream( xSubStream, sStreamName, sMediaType, bCompressed, pBytes ) )
			return false;

		// free the stream resources, garbage collector may remove the object too late
		if ( !disposeStream( xSubStream, sStreamName ) )
			return false;

		return true;
	}

	public boolean WBToSubstrOfEncr( XStorage xStorage,
											  String sStreamName,
											  String sMediaType,
											  boolean bCompressed,
											  byte[] pBytes,
											  boolean bEncrypted )
	{
		// open substream element
		XStream xSubStream = null;
		try
		{
			Object oSubStream = xStorage.openStreamElement( sStreamName, ElementModes.WRITE );
			xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
			if ( xSubStream == null )
			{
				Error( "Can't create substream '" + sStreamName + "'!" );
				return false;
			}
		}
		catch( Exception e )
		{
			Error( "Can't create substream '" + sStreamName + "', exception : " + e + "!" );
			return false;
		}

		// get access to the XPropertySet interface
		XPropertySet xPropSet = (XPropertySet) UnoRuntime.queryInterface( XPropertySet.class, xSubStream );
		if ( xPropSet == null )
		{
			Error( "Can't get XPropertySet implementation from substream '" + sStreamName + "'!" );
			return false;
		}

		// set properties to the stream
		try
		{
			xPropSet.setPropertyValue( "UseCommonStoragePasswordEncryption", new Boolean( bEncrypted ) );
		}
		catch( Exception e )
		{
			Error( "Can't set 'UseCommonStoragePasswordEncryption' property to substream '" + sStreamName + "', exception: " + e );
			return false;
		}

		if ( !WriteBytesToStream( xSubStream, sStreamName, sMediaType, bCompressed, pBytes ) )
			return false;

		// free the stream resources, garbage collector may remove the object too late
		if ( !disposeStream( xSubStream, sStreamName ) )
			return false;

		return true;
	}

	public boolean WriteBytesToStreamH( XStorage xStorage,
										  String sStreamPath,
										  String sMediaType,
										  boolean bCompressed,
										  byte[] pBytes,
										  boolean bCommit )
	{
		// open substream element
		XStream xSubStream = null;
		try
		{
			XHierarchicalStorageAccess xHStorage =
				(XHierarchicalStorageAccess) UnoRuntime.queryInterface( XHierarchicalStorageAccess.class, xStorage );
			if ( xHStorage == null )
			{
				Error( "The storage does not support hierarchical access!" );
				return false;
			}

			Object oSubStream = xHStorage.openStreamElementByHierarchicalName( sStreamPath, ElementModes.WRITE );
			xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
			if ( xSubStream == null )
			{
				Error( "Can't create substream '" + sStreamPath + "'!" );
				return false;
			}
		}
		catch( Exception e )
		{
			Error( "Can't create substream '" + sStreamPath + "', exception : " + e + "!" );
			return false;
		}

		if ( !WriteBytesToStream( xSubStream, sStreamPath, sMediaType, bCompressed, pBytes ) )
			return false;

		XTransactedObject xTransact =
			(XTransactedObject) UnoRuntime.queryInterface( XTransactedObject.class, xSubStream );
		if ( xTransact == null )
		{
			Error( "Substream '" + sStreamPath + "', stream opened for writing must be transacted!" );
			return false;
		}

		if ( bCommit )
		{
			try {
				xTransact.commit();
			} catch( Exception e )
			{
				Error( "Can't commit storage after substream '" + sStreamPath + "' change, exception : " + e + "!" );
				return false;
			}
		}

		// free the stream resources, garbage collector may remove the object too late
		if ( !disposeStream( xSubStream, sStreamPath ) )
			return false;

		return true;
	}

	public boolean WriteBytesToEncrStreamH( XStorage xStorage,
										  String sStreamPath,
										  String sMediaType,
										  boolean bCompressed,
										  byte[] pBytes,
										  String sPass,
										  boolean bCommit )
	{
		// open substream element
		XStream xSubStream = null;
		try
		{
			XHierarchicalStorageAccess xHStorage =
				(XHierarchicalStorageAccess) UnoRuntime.queryInterface( XHierarchicalStorageAccess.class, xStorage );
			if ( xHStorage == null )
			{
				Error( "The storage does not support hierarchical access!" );
				return false;
			}

			Object oSubStream = xHStorage.openEncryptedStreamElementByHierarchicalName( sStreamPath,
																						ElementModes.WRITE,
																						sPass );
			xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
			if ( xSubStream == null )
			{
				Error( "Can't create substream '" + sStreamPath + "'!" );
				return false;
			}
		}
		catch( Exception e )
		{
			Error( "Can't create substream '" + sStreamPath + "', exception : " + e + "!" );
			return false;
		}

		if ( !WriteBytesToStream( xSubStream, sStreamPath, sMediaType, bCompressed, pBytes ) )
			return false;

		XTransactedObject xTransact =
			(XTransactedObject) UnoRuntime.queryInterface( XTransactedObject.class, xSubStream );
		if ( xTransact == null )
		{
			Error( "Substream '" + sStreamPath + "', stream opened for writing must be transacted!" );
			return false;
		}

		if ( bCommit )
		{
			try {
				xTransact.commit();
			} catch( Exception e )
			{
				Error( "Can't commit storage after substream '" + sStreamPath + "' change, exception : " + e + "!" );
				return false;
			}
		}

		// free the stream resources, garbage collector may remove the object too late
		if ( !disposeStream( xSubStream, sStreamPath ) )
			return false;

		return true;
	}

	public boolean WBToSubstrOfEncrH( XStorage xStorage,
									  String sStreamPath,
									  String sMediaType,
									  boolean bCompressed,
									  byte[] pBytes,
									  boolean bEncrypted,
									  boolean bCommit )
	{
		// open substream element
		XStream xSubStream = null;
		try
		{
			XHierarchicalStorageAccess xHStorage =
				(XHierarchicalStorageAccess) UnoRuntime.queryInterface( XHierarchicalStorageAccess.class, xStorage );
			if ( xHStorage == null )
			{
				Error( "The storage does not support hierarchical access!" );
				return false;
			}

			Object oSubStream = xHStorage.openStreamElementByHierarchicalName( sStreamPath, ElementModes.WRITE );
			xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
			if ( xSubStream == null )
			{
				Error( "Can't create substream '" + sStreamPath + "'!" );
				return false;
			}
		}
		catch( Exception e )
		{
			Error( "Can't create substream '" + sStreamPath + "', exception : " + e + "!" );
			return false;
		}

		// get access to the XPropertySet interface
		XPropertySet xPropSet = (XPropertySet) UnoRuntime.queryInterface( XPropertySet.class, xSubStream );
		if ( xPropSet == null )
		{
			Error( "Can't get XPropertySet implementation from substream '" + sStreamPath + "'!" );
			return false;
		}

		// set properties to the stream
		try
		{
			xPropSet.setPropertyValue( "UseCommonStoragePasswordEncryption", new Boolean( bEncrypted ) );
		}
		catch( Exception e )
		{
			Error( "Can't set 'UseCommonStoragePasswordEncryption' property to substream '" + sStreamPath + "', exception: " + e );
			return false;
		}

		if ( !WriteBytesToStream( xSubStream, sStreamPath, sMediaType, bCompressed, pBytes ) )
			return false;

		XTransactedObject xTransact =
			(XTransactedObject) UnoRuntime.queryInterface( XTransactedObject.class, xSubStream );
		if ( xTransact == null )
		{
			Error( "Substream '" + sStreamPath + "', stream opened for writing must be transacted!" );
			return false;
		}

		if ( bCommit )
		{
			try {
				xTransact.commit();
			} catch( Exception e )
			{
				Error( "Can't commit storage after substream '" + sStreamPath + "' change, exception : " + e + "!" );
				return false;
			}
		}

		// free the stream resources, garbage collector may remove the object too late
		if ( !disposeStream( xSubStream, sStreamPath ) )
			return false;

		return true;
	}

	public int ChangeStreamPass( XStorage xStorage,
								 String sStreamName,
								 String sOldPass,
								 String sNewPass )
	{
		// open substream element
		XStream xSubStream = null;
		try
		{
			Object oSubStream = xStorage.openEncryptedStreamElement( sStreamName, ElementModes.WRITE, sOldPass );
			xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
			if ( xSubStream == null )
			{
				Error( "Can't open substream '" + sStreamName + "'!" );
				return 0;
			}
		}
		catch( Exception e )
		{
			Error( "Can't open substream '" + sStreamName + "', exception : " + e + "!" );
			return 0;
		}


		// change the password for the stream
		XEncryptionProtectedSource xStreamEncryption =
				(XEncryptionProtectedSource) UnoRuntime.queryInterface( XEncryptionProtectedSource.class, xSubStream );

		if ( xStreamEncryption == null )
		{
			Message( "Optional interface XEncryptionProtectedSource is not implemented, feature can not be tested!" );
			return -1;
		}

		try {
			xStreamEncryption.setEncryptionPassword( sNewPass );
		}
		catch( Exception e )
		{
			Error( "Can't change encryption key of the substream '" + sStreamName + "', exception:" + e );
			return 0;
		}

		// free the stream resources, garbage collector may remove the object too late
		if ( !disposeStream( xSubStream, sStreamName ) )
			return 0;

		return 1;
	}

	public int ChangeStreamPassH( XStorage xStorage,
								 String sPath,
								 String sOldPass,
								 String sNewPass,
								 boolean bCommit )
	{
		// open substream element
		XHierarchicalStorageAccess xHStorage =
			(XHierarchicalStorageAccess) UnoRuntime.queryInterface( XHierarchicalStorageAccess.class, xStorage );
		if ( xHStorage == null )
		{
			Error( "The storage does not support hierarchical access!" );
			return 0;
		}

		XStream xSubStream = null;
		try
		{
			Object oSubStream = xHStorage.openEncryptedStreamElementByHierarchicalName( sPath, ElementModes.WRITE, sOldPass );
			xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
			if ( xSubStream == null )
			{
				Error( "Can't open encrypted substream '" + sPath + "'!" );
				return 0;
			}
		}
		catch( Exception e )
		{
			Error( "Can't open encrypted substream '" + sPath + "', exception : " + e + "!" );
			return 0;
		}

		// change the password for the stream
		XEncryptionProtectedSource xStreamEncryption =
				(XEncryptionProtectedSource) UnoRuntime.queryInterface( XEncryptionProtectedSource.class, xSubStream );

		if ( xStreamEncryption == null )
		{
			Message( "Optional interface XEncryptionProtectedSource is not implemented, feature can not be tested!" );
			return -1;
		}

		try {
			xStreamEncryption.setEncryptionPassword( sNewPass );
		}
		catch( Exception e )
		{
			Error( "Can't change encryption key of the substream '" + sPath + "', exception:" + e );
			return 0;
		}

		XTransactedObject xTransact =
			(XTransactedObject) UnoRuntime.queryInterface( XTransactedObject.class, xSubStream );
		if ( xTransact == null )
		{
			Error( "Substream '" + sPath + "', stream opened for writing must be transacted!" );
			return 0;
		}

		if ( bCommit )
		{
			try {
				xTransact.commit();
			} catch( Exception e )
			{
				Error( "Can't commit storage after substream '" + sPath + "' change, exception : " + e + "!" );
				return 0;
			}
		}

		// free the stream resources, garbage collector may remove the object too late
		if ( !disposeStream( xSubStream, sPath ) )
			return 0;

		return 1;
	}

	public boolean setStorageTypeAndCheckProps( XStorage xStorage, String sMediaType, boolean bIsRoot, int nMode )
	{
		boolean bOk = false;

		// get access to the XPropertySet interface
		XPropertySet xPropSet = (XPropertySet) UnoRuntime.queryInterface( XPropertySet.class, xStorage );
		if ( xPropSet != null )
		{
			try
			{
				// set "MediaType" property to the stream
				xPropSet.setPropertyValue( "MediaType", sMediaType );

				// get "IsRoot" and "OpenMode" properties and control there values
				boolean bPropIsRoot = AnyConverter.toBoolean( xPropSet.getPropertyValue( "IsRoot" ) );
				int nPropMode = AnyConverter.toInt( xPropSet.getPropertyValue( "OpenMode" ) );

				bOk = true;
				if ( bPropIsRoot != bIsRoot )
				{
					Error( "'IsRoot' property contains wrong value!" );
					bOk = false;
				}

				if ( ( bIsRoot
				  && ( nPropMode | ElementModes.READ ) != ( nMode | ElementModes.READ ) )
				  || ( !bIsRoot && ( nPropMode & nMode ) != nMode ) )
				{
					Error( "'OpenMode' property contains wrong value, expected " + nMode + ", in reality " + nPropMode + "!" );
					bOk = false;
				}
			}
			catch( Exception e )
			{
				Error( "Can't control properties of substorage, exception: " + e );
			}
		}
		else
		{
			Error( "Can't get XPropertySet implementation from storage!" );
		}

		return bOk;
	}

	public boolean checkStorageProperties( XStorage xStorage, String sMediaType, boolean bIsRoot, int nMode )
	{
		boolean bOk = false;

		// get access to the XPropertySet interface
		XPropertySet xPropSet = (XPropertySet) UnoRuntime.queryInterface( XPropertySet.class, xStorage );
		if ( xPropSet != null )
		{
			try
			{
				// get "MediaType", "IsRoot" and "OpenMode" properties and control there values
				String sPropMediaType = AnyConverter.toString( xPropSet.getPropertyValue( "MediaType" ) );
				boolean bPropIsRoot = AnyConverter.toBoolean( xPropSet.getPropertyValue( "IsRoot" ) );
				int nPropMode = AnyConverter.toInt( xPropSet.getPropertyValue( "OpenMode" ) );

				bOk = true;
				if ( !sPropMediaType.equals( sMediaType ) )
				{
					Error( "'MediaType' property contains wrong value, expected '"
							+ sMediaType + "', set '" + sPropMediaType + "' !" );
					bOk = false;
				}

				if ( bPropIsRoot != bIsRoot )
				{
					Error( "'IsRoot' property contains wrong value!" );
					bOk = false;
				}

				if ( ( bIsRoot
				  && ( nPropMode | ElementModes.READ ) != ( nMode | ElementModes.READ ) )
				  || ( !bIsRoot && ( nPropMode & nMode ) != nMode ) )
				{
					Error( "'OpenMode' property contains wrong value, expected " + nMode + ", in reality " + nPropMode + "!" );
					bOk = false;
				}
			}
			catch( Exception e )
			{
				Error( "Can't get properties of substorage, exception: " + e );
			}
		}
		else
		{
			Error( "Can't get XPropertySet implementation from storage!" );
		}

		return bOk;
	}

	public boolean InternalCheckStream( XStream xStream,
										String sName,
										String sMediaType,
                                        boolean bCompressed,
										byte[] pBytes,
                                        boolean bCheckCompressed )
	{
		// get input stream of substream
		XInputStream xInput = xStream.getInputStream();
		if ( xInput == null )
		{
			Error( "Can't get XInputStream implementation from substream '" + sName + "'!" );
			return false;
		}

		byte pContents[][] = new byte[1][]; // ???

		// read contents
		try
		{
			xInput.readBytes( pContents, pBytes.length + 1 );
		}
		catch( Exception e )
		{
			Error( "Can't read from stream '" + sName + "', exception: " + e );
			return false;
		}

		// check size of stream data
		if ( pContents.length == 0 )
		{
			Error( "SubStream '" + sName + "' reading produced disaster!"  );
			return false;
		}

		if ( pBytes.length != pContents[0].length )
		{
			Error( "SubStream '" + sName + "' contains wrong amount of data! (" + pContents[0].length + "/" + pBytes.length + ")" );
			return false;
		}

		// check stream data
		for ( int ind = 0; ind < pBytes.length; ind++ )
		{
			if ( pBytes[ind] != pContents[0][ind] )
			{
				Error( "SubStream '" + sName + "' contains wrong data! ( byte num. "
						+ ind + " should be " + pBytes[ind] + " but it is " + pContents[0][ind] + ")" );
				return false;
			}
		}

		// check properties
		boolean bOk = false;

		// get access to the XPropertySet interface
		XPropertySet xPropSet = (XPropertySet) UnoRuntime.queryInterface( XPropertySet.class, xStream );
		if ( xPropSet != null )
		{
			try
			{
				// get "MediaType" and "Size" properties and control there values
				String sPropMediaType = AnyConverter.toString( xPropSet.getPropertyValue( "MediaType" ) );
				int nPropSize = AnyConverter.toInt( xPropSet.getPropertyValue( "Size" ) );
                boolean bPropCompress = AnyConverter.toBoolean( xPropSet.getPropertyValue( "Compressed" ) );

				bOk = true;
				if ( !sPropMediaType.equals( sMediaType ) )
				{
					Error( "'MediaType' property contains wrong value for stream '" + sName + "',\nexpected: '"
							+ sMediaType + "', set: '" + sPropMediaType + "'!" );
					bOk = false;
				}

				if ( nPropSize != pBytes.length )
				{
					Error( "'Size' property contains wrong value for stream'" + sName + "'!" );
					bOk = false;
				}

                if ( bCheckCompressed && bPropCompress != bCompressed )
                {
    				Error( "'Compressed' property contains wrong value for stream'" + sName + "'!" );
					bOk = false;
                }
			}
			catch( Exception e )
			{
				Error( "Can't get properties of substream '" + sName + "', exception: " + e );
			}
		}
		else
		{
			Error( "Can't get XPropertySet implementation from stream '" + sName + "'!" );
		}

		return bOk;
	}

	public boolean checkStream( XStorage xParentStorage,
								String sName,
								String sMediaType,
                                boolean bCompressed,
								byte[] pBytes )
	{
		// open substream element first
		XStream xSubStream = null;
		try
		{
			Object oSubStream = xParentStorage.openStreamElement( sName, ElementModes.READ );
			xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
			if ( xSubStream == null )
			{
				Error( "Can't open substream '" + sName + "'!" );
				return false;
			}
		}
		catch( Exception e )
		{
			Error( "Can't open substream '" + sName + "', exception : " + e + "!" );
			return false;
		}

		boolean bResult = InternalCheckStream( xSubStream, sName, sMediaType, bCompressed, pBytes, true );

		// free the stream resources, garbage collector may remove the object too late
		if ( !disposeStream( xSubStream, sName ) )
			return false;

		return bResult;
	}

	public boolean checkEncrStream( XStorage xParentStorage,
									String sName,
									String sMediaType,
									byte[] pBytes,
									String sPass )
	{
		// Important: a common password for any of parent storage should not be set or
		// 			  should be different from sPass

		try
		{
			Object oSubStream = xParentStorage.openStreamElement( sName, ElementModes.READ );
			Error( "Encrypted stream '" + sName + "' was opened without password!" );
			return false;
		}
		catch( WrongPasswordException wpe )
		{}
		catch( Exception e )
		{
			Error( "Unexpected exception in case of opening of encrypted stream '" + sName + "' without password: " + e + "!" );
			return false;
		}

		String sWrongPass = "11";
		sWrongPass += sPass;
		try
		{
			Object oSubStream = xParentStorage.openEncryptedStreamElement( sName, ElementModes.READ, sWrongPass );
			Error( "Encrypted stream '" + sName + "' was opened with wrong password!" );
			return false;
		}
		catch( WrongPasswordException wpe )
		{}
		catch( Exception e )
		{
			Error( "Unexpected exception in case of opening of encrypted stream '" + sName + "' with wrong password: " + e + "!" );
			return false;
		}

		XStream xSubStream = null;
		try
		{
			Object oSubStream = xParentStorage.openEncryptedStreamElement( sName, ElementModes.READ, sPass );
			xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
			if ( xSubStream == null )
			{
				Error( "Can't open encrypted substream '" + sName + "'!" );
				return false;
			}
		}
		catch( Exception e )
		{
			Error( "Can't open encrypted substream '" + sName + "', exception : " + e + "!" );
			return false;
		}

        // encrypted streams will be compressed always, so after the storing this property is always true,
        // although before the storing it can be set to false ( it is not always clear whether a stream is encrypted
        // before the storing )
		boolean bResult = InternalCheckStream( xSubStream, sName, sMediaType, true, pBytes, false );

		// free the stream resources, garbage collector may remove the object too late
		if ( !disposeStream( xSubStream, sName ) )
			return false;

		return bResult;
	}

	public boolean checkStreamH( XStorage xParentStorage,
								String sPath,
								String sMediaType,
                                boolean bCompressed,
								byte[] pBytes )
	{
		// open substream element first
		XStream xSubStream = null;
		try
		{
			XHierarchicalStorageAccess xHStorage =
				(XHierarchicalStorageAccess) UnoRuntime.queryInterface( XHierarchicalStorageAccess.class, xParentStorage );
			if ( xHStorage == null )
			{
				Error( "The storage does not support hierarchical access!" );
				return false;
			}

			Object oSubStream = xHStorage.openStreamElementByHierarchicalName( sPath, ElementModes.READ );
			xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
			if ( xSubStream == null )
			{
				Error( "Can't open substream '" + sPath + "'!" );
				return false;
			}
		}
		catch( Exception e )
		{
			Error( "Can't open substream '" + sPath + "', exception : " + e + "!" );
			return false;
		}

		boolean bResult = InternalCheckStream( xSubStream, sPath, sMediaType, bCompressed, pBytes, true );

		// free the stream resources, garbage collector may remove the object too late
		if ( !disposeStream( xSubStream, sPath ) )
			return false;

		return bResult;
	}

	public boolean checkEncrStreamH( XStorage xParentStorage,
									String sPath,
									String sMediaType,
									byte[] pBytes,
									String sPass )
	{
		// Important: a common password for any of parent storage should not be set or
		// 			  should be different from sPass
		XHierarchicalStorageAccess xHStorage =
			(XHierarchicalStorageAccess) UnoRuntime.queryInterface( XHierarchicalStorageAccess.class, xParentStorage );
		if ( xHStorage == null )
		{
			Error( "The storage does not support hierarchical access!" );
			return false;
		}

		try
		{
			Object oSubStream = xHStorage.openStreamElementByHierarchicalName( sPath, ElementModes.READ );
			XStream xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
			Error( "Encrypted substream '" + sPath + "' was opened without password!" );
			return false;
		}
		catch( WrongPasswordException wpe )
		{}
		catch( Exception e )
		{
			Error( "Unexpected exception in case of opening of encrypted stream '" + sPath + "' without password: " + e + "!" );
			return false;
		}

		String sWrongPass = "11";
		sWrongPass += sPass;
		try
		{
			Object oSubStream = xHStorage.openEncryptedStreamElementByHierarchicalName( sPath, ElementModes.READ, sWrongPass );
			XStream xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
			Error( "Encrypted substream '" + sPath + "' was opened with wrong password!" );
			return false;
		}
		catch( WrongPasswordException wpe )
		{}
		catch( Exception e )
		{
			Error( "Unexpected exception in case of opening of encrypted stream '" + sPath + "' with wrong password: " + e + "!" );
			return false;
		}

		XStream xSubStream = null;
		try
		{
			Object oSubStream = xHStorage.openEncryptedStreamElementByHierarchicalName( sPath, ElementModes.READ, sPass );
			xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
			if ( xSubStream == null )
			{
				Error( "Can't open encrypted substream '" + sPath + "'!" );
				return false;
			}
		}
		catch( Exception e )
		{
			Error( "Can't open encrypted substream '" + sPath + "', exception : " + e + "!" );
			return false;
		}

        // encrypted streams will be compressed always, so after the storing this property is always true,
        // although before the storing it can be set to false ( it is not always clear whether a stream is encrypted
        // before the storing )
		boolean bResult = InternalCheckStream( xSubStream, sPath, sMediaType, true, pBytes, false );

		// free the stream resources, garbage collector may remove the object too late
		if ( !disposeStream( xSubStream, sPath ) )
			return false;

		return bResult;
	}

	public boolean copyStorage( XStorage xSourceStorage, XStorage xDestStorage )
	{
		// copy xSourceStorage to xDestStorage
		try
		{
			xSourceStorage.copyToStorage( xDestStorage );
		}
		catch( Exception e )
		{
			Error( "Storage copying failed, exception: " + e );
			return false;
		}

		return true;
	}

	public boolean commitStorage( XStorage xStorage )
	{
		// XTransactedObject must be supported by storages
		XTransactedObject xTransact = (XTransactedObject) UnoRuntime.queryInterface( XTransactedObject.class, xStorage );
		if ( xTransact == null )
		{
			Error( "Storage doesn't implement transacted access!" );
			return false;
		}

		try
		{
			xTransact.commit();
		}
		catch( Exception e )
		{
			Error( "Storage commit failed, exception:" + e );
			return false;
		}

		return true;
	}

	public boolean disposeStream( XStream xStream, String sStreamName )
	{
		XComponent xComponent = (XComponent) UnoRuntime.queryInterface( XComponent.class, xStream );
		if ( xComponent == null )
		{
			Error( "Can't get XComponent implementation from substream '" + sStreamName + "'!" );
			return false;
		}

		try
		{
			xComponent.dispose();
		}
		catch( Exception e )
		{
			Error( "Substream '" + sStreamName + "' disposing throws exception: " + e );
			return false;
		}

		return true;
	}

	public boolean disposeStorage( XStorage xStorage )
	{
		// dispose the storage
		XComponent xComponent = (XComponent) UnoRuntime.queryInterface( XComponent.class, xStorage );
		if ( xComponent == null )
		{
			Error( "Can't retrieve XComponent implementation from storage!" );
			return false;
		}

		try
		{
			xComponent.dispose();
		}
		catch( Exception e )
		{
			Error( "Storage disposing failed!" );
			return false;
		}

		return true;
	}

	public XInputStream getInputStream( XStream xStream )
	{
		XInputStream xInTemp = null;
		try
		{
			xInTemp = xStream.getInputStream();
			if ( xInTemp == null )
				Error( "Can't get the input part of a stream!" );
		}
		catch ( Exception e )
		{
			Error( "Can't get the input part of a stream, exception :" + e );
		}

		return xInTemp;
	}

	public boolean closeOutput( XStream xStream )
	{
		XOutputStream xOutTemp = null;
		try
		{
			xOutTemp = xStream.getOutputStream();
			if ( xOutTemp == null )
			{
				Error( "Can't get the output part of a stream!" );
				return false;
			}
		}
		catch ( Exception e )
		{
			Error( "Can't get the output part of a stream, exception :" + e );
			return false;
		}

		try
		{
			xOutTemp.closeOutput();
		}
		catch ( Exception e )
		{
			Error( "Can't close output part of a stream, exception :" + e );
			return false;
		}

		return true;
	}

	public XStorage openSubStorage( XStorage xStorage, String sName, int nMode )
	{
		// open existing substorage
		try
		{
			Object oSubStorage = xStorage.openStorageElement( sName, nMode );
			XStorage xSubStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oSubStorage );
			return xSubStorage;
		}
		catch( Exception e )
		{
			Error( "Can't open substorage '" + sName + "', exception: " + e );
		}

		return null;
	}

	public XStream CreateTempFileStream( XMultiServiceFactory xMSF )
	{
		// try to get temporary file representation
		XStream xTempFileStream = null;
		try
		{
			Object oTempFile = xMSF.createInstance( "com.sun.star.io.TempFile" );
			xTempFileStream = (XStream)UnoRuntime.queryInterface( XStream.class, oTempFile );
		}
		catch( Exception e )
		{}

		if ( xTempFileStream == null )
			Error( "Can't create temporary file!" );

		return xTempFileStream;
	}

	public String CreateTempFile( XMultiServiceFactory xMSF )
	{
		String sResult = null;

		// try to get temporary file representation
		XPropertySet xTempFileProps = null;
		try
		{
			Object oTempFile = xMSF.createInstance( "com.sun.star.io.TempFile" );
			xTempFileProps = (XPropertySet)UnoRuntime.queryInterface( XPropertySet.class, oTempFile );
		}
		catch( Exception e )
		{}

		if ( xTempFileProps != null )
		{
			try
			{
				xTempFileProps.setPropertyValue( "RemoveFile", new Boolean( false ) );
				sResult = AnyConverter.toString( xTempFileProps.getPropertyValue( "Uri" ) );
			}
			catch( Exception e )
			{
				Error( "Can't control TempFile properties, exception: " + e );
			}
		}
		else
		{
			Error( "Can't create temporary file representation!" );
		}

		// close temporary file explicitly
		try
		{
			XStream xStream = (XStream)UnoRuntime.queryInterface( XStream.class, xTempFileProps );
			if ( xStream != null )
			{
				XOutputStream xOut = xStream.getOutputStream();
				if ( xOut != null )
					xOut.closeOutput();

				XInputStream xIn = xStream.getInputStream();
				if ( xIn != null )
					xIn.closeInput();
			}
			else
				Error( "Can't close TempFile!" );
		}
		catch( Exception e )
		{
			Error( "Can't close TempFile, exception: " + e );
		}

		return sResult;
	}

	public boolean copyElementTo( XStorage xSource, String sName, XStorage xDest )
	{
		// copy element with name sName from xSource to xDest
		try
		{
			xSource.copyElementTo( sName, xDest, sName );
		}
		catch( Exception e )
		{
			Error( "Element copying failed, exception: " + e );
			return false;
		}

		return true;
	}

	public boolean copyElementTo( XStorage xSource, String sName, XStorage xDest, String sTargetName )
	{
		// copy element with name sName from xSource to xDest
		try
		{
			xSource.copyElementTo( sName, xDest, sTargetName );
		}
		catch( Exception e )
		{
			Error( "Element copying failed, exception: " + e );
			return false;
		}

		return true;
	}

	public boolean moveElementTo( XStorage xSource, String sName, XStorage xDest )
	{
		// move element with name sName from xSource to xDest
		try
		{
			xSource.moveElementTo( sName, xDest, sName );
		}
		catch( Exception e )
		{
			Error( "Element moving failed, exception: " + e );
			return false;
		}

		return true;
	}

	public boolean renameElement( XStorage xStorage, String sOldName, String sNewName )
	{
		// rename element with name sOldName to sNewName
		try
		{
			xStorage.renameElement( sOldName, sNewName );
		}
		catch( Exception e )
		{
			Error( "Element renaming failed, exception: " + e );
			return false;
		}

		return true;
	}

	public boolean removeElement( XStorage xStorage, String sName )
	{
		// remove element with name sName
		try
		{
			xStorage.removeElement( sName );
		}
		catch( Exception e )
		{
			Error( "Element removing failed, exception: " + e );
			return false;
		}

		return true;
	}

	public XStream OpenStream( XStorage xStorage,
								String sStreamName,
								int nMode )
	{
		// open substream element
		XStream xSubStream = null;
		try
		{
			Object oSubStream = xStorage.openStreamElement( sStreamName, nMode );
			xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
			if ( xSubStream == null )
				Error( "Can't create substream '" + sStreamName + "'!" );
		}
		catch( Exception e )
		{
			Error( "Can't create substream '" + sStreamName + "', exception : " + e + "!" );
		}

		return xSubStream;
	}

	public boolean compareRawMethodsOnEncrStream( XStorage xStorage, String sStreamName )
	{

		XStorageRawAccess xRawStorage;
		try
		{
			xRawStorage = (XStorageRawAccess) UnoRuntime.queryInterface( XStorageRawAccess.class, xStorage );
		}
		catch( Exception e )
		{
			Error( "Can't get raw access to the storage, exception : " + e + "!" );
			return false;
		}

		if ( xRawStorage == null )
		{
			Error( "Can't get raw access to the storage!" );
			return false;
		}

		XInputStream xHeadRawStream = null;
		try
		{
			xHeadRawStream = xRawStorage.getRawEncrStreamElement( sStreamName );
		}
		catch( Exception e )
		{
			Error( "Can't open encrypted stream '" + sStreamName + "' in raw mode with header, exception : " + e + "!" );
		}

		XInputStream xPlainRawStream = null;
		try
		{
			xPlainRawStream = xRawStorage.getPlainRawStreamElement( sStreamName );
		}
		catch( Exception e )
		{
			Error( "Can't open encrypted stream '" + sStreamName + "' in raw mode with header, exception : " + e + "!" );
		}

		if ( xHeadRawStream == null || xPlainRawStream == null )
		{
			Error( "Can't open encrypted stream '" + sStreamName + "' in raw modes!" );
			return false;
		}

		try
		{
			byte pData[][] = new byte[1][38];
			if ( xHeadRawStream.readBytes( pData, 38 ) != 38 )
			{
				Error( "Can't read header of encrypted stream '" + sStreamName + "' raw representations!" );
				return false;
			}

			if ( pData[0][0] != 0x4d || pData[0][1] != 0x4d || pData[0][2] != 0x02 || pData[0][3] != 0x05 )
			{
				Error( "No signature in the header of encrypted stream '" + sStreamName + "' raw representations!" );
				return false;
			}

			int nVariableHeaderLength =
						( pData[0][30] + pData[0][31] * 0x100 ) // salt length
						+ ( pData[0][32] + pData[0][33] * 0x100 ) // iv length
						+ ( pData[0][34] + pData[0][35] * 0x100 ) // digest length
						+ ( pData[0][36] + pData[0][37] * 0x100 ); // mediatype length

			xHeadRawStream.skipBytes( nVariableHeaderLength );

			byte pRawData1[][] = new byte[1][32000];
			byte pRawData2[][] = new byte[1][32000];
			int nRead1 = 0;
			int nRead2 = 0;

			do
			{
				nRead1 = xHeadRawStream.readBytes( pRawData1, 32000 );
				nRead2 = xPlainRawStream.readBytes( pRawData2, 32000 );

				if ( nRead1 != nRead2 )
				{
					Error( "The encrypted stream '" + sStreamName + "' raw representations have different size! nRead1 - nRead2 = " + ( new Integer( nRead1 - nRead2 ) ).toString() );
					return false;
				}

				for ( int nInd = 0; nInd < nRead1; nInd++ )
					if ( pRawData1[0][nInd] != pRawData2[0][nInd] )
					{
						Error( "The encrypted stream '" + sStreamName + "' raw representations have different data!" );
						return false;
					}
			}
			while( nRead1 == 32000 );
		}
		catch ( Exception e )
		{
			Error( "Can't compare stream '" + sStreamName + "' raw representations, exception : " + e + "!" );
			return false;
		}

		return true;
	}

	public boolean cantOpenStorage( XStorage xStorage, String sName )
	{
		// try to open an opened substorage, open call must fail
		try
		{
			Object oDummyStorage = xStorage.openStorageElement( sName, ElementModes.READ );
			Error( "The trying to reopen opened substorage '" + sName + "' must fail!" );
		}
		catch( Exception e )
		{
			return true;
		}

		return false;
	}

	public boolean cantOpenStream( XStorage xStorage, String sName, int nMode )
	{
		// try to open the substream with specified mode must fail
		try
		{
			Object oDummyStream = xStorage.openStreamElement( sName, nMode );
			Error( "The trying to open substream '" + sName + "' must fail!" );
		}
		catch( Exception e )
		{
			return true;
		}

		return false;
	}

	public boolean cantOpenStreamH( XStorage xStorage, String sPath, int nMode )
	{
		// try to open the substream with specified mode must fail

		XHierarchicalStorageAccess xHStorage =
			(XHierarchicalStorageAccess) UnoRuntime.queryInterface( XHierarchicalStorageAccess.class, xStorage );
		if ( xHStorage == null )
		{
			Error( "The storage does not support hierarchical access!" );
			return false;
		}

		try
		{
			Object oDummyStream = xHStorage.openStreamElementByHierarchicalName( sPath, nMode );
			Error( "The trying to open substream '" + sPath + "' must fail!" );
		}
		catch( Exception e )
		{
			return true;
		}

		return false;
	}

	public boolean cantOpenEncrStreamH( XStorage xStorage, String sPath, int nMode, String aPass )
	{
		// try to open the substream with specified mode must fail

		XHierarchicalStorageAccess xHStorage =
			(XHierarchicalStorageAccess) UnoRuntime.queryInterface( XHierarchicalStorageAccess.class, xStorage );
		if ( xHStorage == null )
		{
			Error( "The storage does not support hierarchical access!" );
			return false;
		}

		try
		{
			Object oDummyStream = xHStorage.openEncryptedStreamElementByHierarchicalName( sPath, nMode, aPass );
			Error( "The trying to open substream '" + sPath + "' must fail!" );
		}
		catch( WrongPasswordException wpe )
		{
			Error( "The substream '" + sPath + "' must not exist!" );
			return false;
		}
		catch( Exception e )
		{
			return true;
		}

		return false;
	}

	public XStorage cloneStorage( XSingleServiceFactory xFactory, XStorage xStorage )
	{
		// create a copy of a last committed version of specified storage
		XStorage xResult = null;
		try
		{
			Object oTempStorage = xFactory.createInstance();
			xResult = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
			if ( xResult != null )
				xStorage.copyLastCommitTo( xResult );
		}
		catch( Exception e )
		{
			Error( "Can't clone storage, exception: " + e );
			return null;
		}

		return xResult;
	}

	public XStorage cloneSubStorage( XSingleServiceFactory xFactory, XStorage xStorage, String sName )
	{
		// create a copy of a last committed version of specified substorage
		XStorage xResult = null;
		try
		{
			Object oTempStorage = xFactory.createInstance();
			xResult = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
			if ( xResult != null )
				xStorage.copyStorageElementLastCommitTo( sName, xResult );
		}
		catch( Exception e )
		{
			Error( "Can't clone substorage '" + sName + "', exception: " + e );
			return null;
		}

		return xResult;
	}

	public XStream cloneSubStream( XStorage xStorage, String sName )
	{
		// clone existing substream
		try
		{
			XStream xStream = xStorage.cloneStreamElement( sName );
			return xStream;
		}
		catch( Exception e )
		{
			Error( "Can't clone substream '" + sName + "', exception: " + e );
		}

		return null;
	}

	public XStream cloneEncrSubStream( XStorage xStorage, String sName, String sPass )
	{
		// clone existing substream
		try
		{
			XStream xStream = xStorage.cloneEncryptedStreamElement( sName, sPass );
			return xStream;
		}
		catch( Exception e )
		{
			Error( "Can't clone encrypted substream '" + sName + "', exception: " + e );
		}

		return null;
	}

	public void Error( String sError )
	{
		m_aLogWriter.println( m_sTestPrefix + "Error: " + sError );
	}

	public void Message( String sMessage )
	{
		m_aLogWriter.println( m_sTestPrefix + sMessage );
	}
}
