Hi Mikhail,

Thanks very much for your advice, I kind of confused the data source and data sink, now I can get the right result from the test, please review it and give me any suggestions on it. :-)

By the way, I still do not quite understand the service. Is a storage, constructed with a XInputStream, any different from one constructed with a XStream? Is the first one read only? If that is the case, maybe it's better I modify the in-idl documentations a little bit to make that clear.

Best Regards,
Felix.


Mikhail Voitenko 写道:
Hi Felix,

I have recognized that readBytes() and writeBytes() seem to be used wrongly.

In general readBytes() reads from the stream to the provided array, and writeBytes() writes to the stream from the provided array.The streams are empty because they were not changed after opening, readBytes() is used at the beginning instead of writeBytes(). So to work as expected the test should first write the data to the stream, and read it at the end of the test.

Best Regards,
Mikhail.


Zhang Xiaofei wrote:
Hi Mikhail,

Thanks for your help in our last IRC meeting, the exception is eliminated, now I got another com.sun.star.io.NotConnectedException in line 96, Test.java, when the statement below is executed:
xTempStream[i].getOutputStream ().writeBytes (pBytesOut[i]);

I debugged the test and found the sub-streams had always been zero-lengthed in the entire test, I could not find out why I got this result, could you please give me some help on this?

Thanks and Best Regards,
Felix.


Zhang Xiaofei 写道:
Hi Mikhail,

The attachment is the unit test for OLESimpleStorage, right now I have a problem running it: a java.lang.ClassCastException in Test01.java, line 89, could you please help me on this? Thanks!

Best Regards,
Felix.

Mikhail Voitenko 写道:
Hi Felix,

Sorry, something seems to go wrong with the mail system. I did not get this mail although I was in CC. Good that it was also sent to dev@framework.openoffice.org

There seems to be no attachments to review, but we have discussed the problems already. So since you have adjusted the tests and they are executed as expected, it is ok to attach them to the related issue I think. I will integrate them along with the changes for TempFile service after the vacation.

The only documentation for the OleSimpleStorage service is the idl-specification written by you :) If you would like to see an example of service usage, please take a look to the embeddedobj project, the service is used in the following files: embeddedobj/source/msole/olepersist.cxx
embeddedobj/source/msole/ownview.cxx

Best Regards,
Mikhail.

Zhang Xiaofei wrote:
Hi Mikhail,

Sorry for the delay, I was tracking a bug all day long yesterday and did not sent out the TempFile tests. I guess this version is functionally OK now. Please check the attachment to review them.

And now that I am to write the test for OleSimpleStorage, could you recommend to me some references on it please? Any example tests or documents on the service/interface could be helpful to me.

Again, thanks very much for your help during the task. :-)

Best Regards,
Felix.


Mikhail Voitenko 写道:
Hi Felix,

Sorry for the delay with the answer.
I think that it will be enough to introduce only one test for OleSimpleStorage based on the scenario that I have already mentioned. Further tests will need additional .doc test files integrated in the test, that is relative complex. So if you want to introduce them, let do it after my vacation, so that I can answer the questions.

Please prepare the test for OleSimpleStorage so we can integrate it together with the service reimplementation. The test suite can be extended in future.

By the way, how is it going with the TempFile tests? You was going to send me the final version. If there are any questions please do not hesitate to ask, so that I can answer before the Friday ( my vacation starts on Friday ).

Thanks,
Mikhail.



------------------------------------------------------------------------

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

------------------------------------------------------------------------

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


dmake: Executing shell macro: echo %_cwd
dmake: Executing shell macro: echo %_4ver
dmake: Executing shell macro: -ls -1 $(JARDIR) | $(GREP) "^$i"
dmake: Executing shell macro: -ls -1 $(JARDIR) | $(GREP) "^$i"
dmake: Executing shell macro: -ls -1 $(JARDIR) | $(GREP) "^$i"
dmake: Executing shell macro: -ls -1 $(JARDIR) | $(GREP) "^$i"
dmake: Executing shell macro: -ls -1 $(JARDIR) | $(GREP) "^$i"
dmake: Executing shell macro: -ls -1 $(JARDIR) | $(GREP) "^$i"
dmake: Executing shell macro: -ls -1 $(JARDIR) | $(GREP) "^$i"
java -cp 
.;..\..\..\wntmsci10.pro\class;d:\OOEnv\J2SDK1~1.2_0\jre\lib\rt.jar;.;f:\OOo\SRC680_m217\solver\680\wntmsci10.pro\bin\ridl.jar;f:\OOo\SRC680_m217\solver\680\wntmsci10.pro\bin\unoil.jar;f:\OOo\SRC680_m217\solver\680\wntmsci10.pro\bin\jurt.jar;f:\OOo\SRC680_m217\solver\680\wntmsci10.pro\bin\juh.jar;f:\OOo\SRC680_m217\solver\680\wntmsci10.pro\bin\jut.jar;f:\OOo\SRC680_m217\solver\680\wntmsci10.pro\bin\java_uno.jar;f:\OOo\SRC680_m217\solver\680\wntmsci10.pro\bin\OOoRunner.jar
 org.openoffice.Runner -TestBase java_complex  -o 
complex.olesimplestorage.OLESimpleStorageUnitTest OLESimpleStorageTest 
TestHelper Test01
TestJob: -o complex.olesimplestorage.OLESimpleStorageUnitTest
Searching Class: complex.olesimplestorage.OLESimpleStorageUnitTest
Got test: [EMAIL PROTECTED]
LOG> Log started 05.08.2007 - 14:26:34
LOG> Starting ExecuteTest01
LOG> Test01: A new temporary stream created.
LOG> Test01: OLESimpleStorage based on XStream created.
LOG> Test01: Substream 0 initialized.
LOG> Test01: Substream 0 inserted.
LOG> Test01: Substream 1 initialized.
LOG> Test01: Substream 1 inserted.
LOG> Test01: Substream 2 initialized.
LOG> Test01: Substream 2 inserted.
LOG> Test01: Substream 3 initialized.
LOG> Test01: Substream 3 inserted.
LOG> Test01: Substream 4 initialized.
LOG> Test01: Substream 4 inserted.
LOG> Test01: Storage commited.
LOG> Test01: Storage closed.
LOG> Test01: Storage reopened, based on XInputStream.
LOG> Test01: Checking data contained in all the substreams...
LOG> Test01: Stream 0 byte 0:  CORRECT.
LOG> Test01: Stream 0 byte 1:  CORRECT.
LOG> Test01: Stream 0 byte 2:  CORRECT.
LOG> Test01: Stream 0 byte 3:  CORRECT.
LOG> Test01: Stream 0 byte 4:  CORRECT.
LOG> Test01: Stream 0 byte 5:  CORRECT.
LOG> Test01: Stream 0 byte 6:  CORRECT.
LOG> Test01: Stream 0 byte 7:  CORRECT.
LOG> Test01: Stream 0 byte 8:  CORRECT.
LOG> Test01: Stream 0 byte 9:  CORRECT.
LOG> Test01: Stream 1 byte 0:  CORRECT.
LOG> Test01: Stream 1 byte 1:  CORRECT.
LOG> Test01: Stream 1 byte 2:  CORRECT.
LOG> Test01: Stream 1 byte 3:  CORRECT.
LOG> Test01: Stream 1 byte 4:  CORRECT.
LOG> Test01: Stream 1 byte 5:  CORRECT.
LOG> Test01: Stream 1 byte 6:  CORRECT.
LOG> Test01: Stream 1 byte 7:  CORRECT.
LOG> Test01: Stream 1 byte 8:  CORRECT.
LOG> Test01: Stream 1 byte 9:  CORRECT.
LOG> Test01: Stream 2 byte 0:  CORRECT.
LOG> Test01: Stream 2 byte 1:  CORRECT.
LOG> Test01: Stream 2 byte 2:  CORRECT.
LOG> Test01: Stream 2 byte 3:  CORRECT.
LOG> Test01: Stream 2 byte 4:  CORRECT.
LOG> Test01: Stream 2 byte 5:  CORRECT.
LOG> Test01: Stream 2 byte 6:  CORRECT.
LOG> Test01: Stream 2 byte 7:  CORRECT.
LOG> Test01: Stream 2 byte 8:  CORRECT.
LOG> Test01: Stream 2 byte 9:  CORRECT.
LOG> Test01: Stream 3 byte 0:  CORRECT.
LOG> Test01: Stream 3 byte 1:  CORRECT.
LOG> Test01: Stream 3 byte 2:  CORRECT.
LOG> Test01: Stream 3 byte 3:  CORRECT.
LOG> Test01: Stream 3 byte 4:  CORRECT.
LOG> Test01: Stream 3 byte 5:  CORRECT.
LOG> Test01: Stream 3 byte 6:  CORRECT.
LOG> Test01: Stream 3 byte 7:  CORRECT.
LOG> Test01: Stream 3 byte 8:  CORRECT.
LOG> Test01: Stream 3 byte 9:  CORRECT.
LOG> Test01: Stream 4 byte 0:  CORRECT.
LOG> Test01: Stream 4 byte 1:  CORRECT.
LOG> Test01: Stream 4 byte 2:  CORRECT.
LOG> Test01: Stream 4 byte 3:  CORRECT.
LOG> Test01: Stream 4 byte 4:  CORRECT.
LOG> Test01: Stream 4 byte 5:  CORRECT.
LOG> Test01: Stream 4 byte 6:  CORRECT.
LOG> Test01: Stream 4 byte 7:  CORRECT.
LOG> Test01: Stream 4 byte 8:  CORRECT.
LOG> Test01: Stream 4 byte 9:  CORRECT.
LOG> Test01: All substreams contain correct data. SUCCESS.
LOG> Finished ExecuteTest01
***** State for complex.olesimplestorage.OLESimpleStorageUnitTest ******
Whole unit: PASSED.OK
************************************************************************
Job -o complex.olesimplestorage.OLESimpleStorageUnitTest done
#*************************************************************************
#
#   OpenOffice.org - a multi-platform office productivity suite
#
#   $RCSfile: makefile.mk,v $
#
#   $Revision: 1.11 $
#
#   last change: $Author: obo $ $Date: 2006/10/13 11:46:54 $
#
#   The Contents of this file are made available subject to
#   the terms of GNU Lesser General Public License Version 2.1.
#
#
#     GNU Lesser General Public License Version 2.1
#     =============================================
#     Copyright 2005 by Sun Microsystems, Inc.
#     901 San Antonio Road, Palo Alto, CA 94303, USA
#
#     This library is free software; you can redistribute it and/or
#     modify it under the terms of the GNU Lesser General Public
#     License version 2.1, as published by the Free Software Foundation.
#
#     This library is distributed in the hope that it will be useful,
#     but WITHOUT ANY WARRANTY; without even the implied warranty of
#     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#     Lesser General Public License for more details.
#
#     You should have received a copy of the GNU Lesser General Public
#     License along with this library; if not, write to the Free Software
#     Foundation, Inc., 59 Temple Place, Suite 330, Boston,
#     MA  02111-1307  USA
#
#*************************************************************************

PRJ = ..$/..$/..
TARGET  = OLESimpleStorageUnitTest
PRJNAME = sot
PACKAGE = complex$/olesimplestorage

# --- Settings -----------------------------------------------------
.INCLUDE: settings.mk


#----- compile .java files -----------------------------------------

JARFILES        = ridl.jar unoil.jar jurt.jar juh.jar jut.jar java_uno.jar 
OOoRunner.jar

JAVAFILES       =\
                                OLESimpleStorageUnitTest.java\
                                OLESimpleStorageTest.java\
                                TestHelper.java\
                                Test01.java

JAVACLASSFILES  = $(foreach,i,$(JAVAFILES) 
$(CLASSDIR)$/$(PACKAGE)$/$(i:b).class)

#----- make a jar from compiled files ------------------------------

MAXLINELENGTH = 100000

JARCLASSDIRS    = $(PACKAGE)
JARTARGET       = $(TARGET).jar
JARCOMPRESS     = TRUE

# --- Parameters for the test --------------------------------------

# start an office if the parameter is set for the makefile
.IF "$(OFFICE)" == ""
CT_APPEXECCOMMAND =
.ELSE
CT_APPEXECCOMMAND = -AppExecutionCommand "$(OFFICE)$/soffice 
-accept=socket,host=localhost,port=8100;urp;"
.ENDIF

# test base is java complex
CT_TESTBASE = -TestBase java_complex

# test looks something like the.full.package.TestName
CT_TEST     = -o $(PACKAGE:s\$/\.\).$(JAVAFILES:b)

# start the runner application
CT_APP      = org.openoffice.Runner

# --- Targets ------------------------------------------------------

.INCLUDE: target.mk

RUN: run

run:
    +java -cp $(CLASSPATH) $(CT_APP) $(CT_TESTBASE) $(CT_APPEXECCOMMAND) 
$(CT_TEST)


package complex.olesimplestorage;

public interface OLESimpleStorageTest {
    boolean test();
}
/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: StorageUnitTest.java,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: obo $ $Date: 2006/10/13 11:45:51 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
package complex.olesimplestorage;

import complexlib.ComplexTestCase;
import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.uno.UnoRuntime;

/* Document.
 */

public class OLESimpleStorageUnitTest extends ComplexTestCase {
    private XMultiServiceFactory m_xMSF = null;
    
    public String[] getTestMethodNames() {
        return new String[] {
            "ExecuteTest01"};
    }
    
    public String getTestObjectName() {
        return "OLESimpleStorageUnitTest";
    }

    public void before () {
        try {
            m_xMSF = (XMultiServiceFactory)param.getMSF();
        } catch ( Exception e ){
            failed ( "Cannot create service factory!" );
        }
        if ( m_xMSF == null ) {
            failed ( "Cannot create service factory!" );
        }
    }
    
    public void after () {
        m_xMSF = null;
    }
    
    public void ExecuteTest01() {
        OLESimpleStorageTest aTest = new Test01( m_xMSF, log );
        assure( "Test01 failed!", aTest.test() );
    }

}
package complex.olesimplestorage;

/*
import com.sun.star.io.BufferSizeExceededException;
import com.sun.star.io.IOException;
import com.sun.star.io.NotConnectedException;
 */
import complexlib.ComplexTestCase;

import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.io.XInputStream;
import com.sun.star.io.XOutputStream;
import com.sun.star.io.XTempFile;
import com.sun.star.embed.*;
import com.sun.star.uno.UnoRuntime;
import java.util.Random;

import share.LogWriter;

public class Test01 implements OLESimpleStorageTest
{
    LogWriter m_aLogWriter;
    XMultiServiceFactory m_xMSF = null;
    TestHelper m_aTestHelper = null;
    final int pStreamCnt = 5;
    final int pBytesCnt = 10;
  
    
    public Test01 ( XMultiServiceFactory xMSF, LogWriter aLogWriter )
    {
        m_xMSF = xMSF;
        m_aTestHelper = new TestHelper (aLogWriter, "Test01: ");
    }
    
    public boolean test ()
    {
        try
        {
            //create a new temporary stream
            Object oTempFile = m_xMSF.createInstance ( "com.sun.star.io.TempFile" );
            XTempFile xTempFile = (XTempFile) UnoRuntime.queryInterface ( XTempFile.class, oTempFile );
            m_aTestHelper.Message ( "A new temporary stream created." );
            
            //create OLESimpleStorage based on it
            Object pArgs[] = new Object[2];
            pArgs[0] = (Object) xTempFile;
            pArgs[1] = new Boolean( true );
            Object oOLESimpleStorage = m_xMSF.createInstanceWithArguments ( "com.sun.star.embed.OLESimpleStorage", pArgs );
            XOLESimpleStorage xOLESimpleStorage = (XOLESimpleStorage) UnoRuntime.queryInterface ( XOLESimpleStorage.class, oOLESimpleStorage );
            m_aTestHelper.Message ( "OLESimpleStorage based on XStream created." );
            
            //fill it with some streams
            Object oStream[] = new Object[pStreamCnt];
            byte pBytesIn[][][] = new byte [pStreamCnt][1][pBytesCnt];
            byte pBytesOut[][] = new byte [pStreamCnt][pBytesCnt];
            XTempFile xTempStream[] = new XTempFile[pStreamCnt];
            Random oRandom = new Random ();
            final String sSubStreamPrefix = "SubStream";
            for ( int i = 0; i < pStreamCnt; i++ )
            {
                oRandom.nextBytes (pBytesIn[i][0]);
                oStream[i] = m_xMSF.createInstance ( "com.sun.star.io.TempFile" );
                xTempStream[i] = (XTempFile) UnoRuntime.queryInterface ( XTempFile.class, oStream[i] );
                xTempStream[i].getOutputStream ().writeBytes (pBytesOut[i]);
                xTempStream[i].seek (0);
                m_aTestHelper.Message ( "Substream " + i + " initialized." );
                if (xOLESimpleStorage.hasByName (sSubStreamPrefix + i))
                {
                    xOLESimpleStorage.replaceByName ( sSubStreamPrefix + i, xTempStream[i] );
                }
                else
                {
                    xOLESimpleStorage.insertByName ( sSubStreamPrefix + i, xTempStream[i] );
                    m_aTestHelper.Message ( "Substream " + i + " inserted." );
                }
            }
            
            //commit the storage and close it
            xOLESimpleStorage.commit ();
            m_aTestHelper.Message ( "Storage commited." );
            xOLESimpleStorage.dispose ();
            for ( int i = 0; i < pStreamCnt; ++i )
            {
                xTempStream[i].setRemoveFile ( true );
                xTempStream[i].getInputStream ().closeInput ();
                xTempStream[i].getOutputStream ().closeOutput ();
            }
            m_aTestHelper.Message ( "Storage closed." );
            
            //open the same stream with the constructor for inputstream
            pArgs[0] = (Object)xTempFile.getInputStream ();
            oOLESimpleStorage = m_xMSF.createInstanceWithArguments ( "com.sun.star.embed.OLESimpleStorage", pArgs );
            xOLESimpleStorage = (XOLESimpleStorage)UnoRuntime.queryInterface ( XOLESimpleStorage.class, oOLESimpleStorage );
            m_aTestHelper.Message ( "Storage reopened, based on XInputStream." );
            
            //check that all the streams contain correct information
            m_aTestHelper.Message ( "Checking data contained in all the substreams..." );
            for ( int i = 0; i < pStreamCnt; ++i )
            {
                if ( xOLESimpleStorage.hasByName (sSubStreamPrefix + i) )
                {
                    xTempStream[i] = (XTempFile)UnoRuntime.queryInterface ( 
                    XTempFile.class, xOLESimpleStorage.getByName (sSubStreamPrefix + i) );
                    xTempStream[i].seek (0);
                    xTempStream[i].getInputStream ().readBytes (pBytesIn[i], pBytesIn[i][0].length+1);
                    for ( int j = 0; j < pBytesCnt; ++j )
                    {
                        if ( pBytesIn[i][0][j] != pBytesOut[i][j] )
                        {
                            m_aTestHelper.Error ( "Stream " + i + " byte " + j + ": INCORRECT DATA!");
                            return false;
                        }
                        else 
                        {
                            m_aTestHelper.Message ( "Stream " + i + " byte " + j + ":  CORRECT." );
                        }
                    }
                }
                else
                {
                    m_aTestHelper.Error( "Stream " + i + " is lost!");
                    return false;
                }
            }
            m_aTestHelper.Message ( "All substreams contain correct data. SUCCESS." );
        }
        catch ( Exception e )
        {
            m_aTestHelper.Error ( "Exception: " + e );
        }
        return true;
    }
}
package complex.olesimplestorage;

import complexlib.ComplexTestCase;
import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.io.XTempFile;
import com.sun.star.io.XInputStream;
import com.sun.star.io.XOutputStream;
import com.sun.star.embed.*;

import com.sun.star.uno.AnyConverter;
import com.sun.star.ucb.XSimpleFileAccess;
import com.sun.star.uno.UnoRuntime;
import java.util.Random;
import javax.sound.midi.Sequence;
import share.LogWriter;

public class TestHelper
{
    LogWriter m_aLogWriter;
    String m_sTestPrefix;
    final int pBytesCount = 100;
    
    /** Creates a new instance of TestHelper */
    public TestHelper ( LogWriter aLogWriter, String sTestPrefix )
    {
        m_aLogWriter = aLogWriter;
        m_sTestPrefix = sTestPrefix;
    }
    
    public String GetNewTempFileURL ( XMultiServiceFactory xMSF )
    {
        if ( xMSF == null )
        {
            Error ( "No factory provided." );
            return null;
        }
        try
        {
            String sResult;
            Object oTempFile = xMSF.createInstance ( "com.sun.star.io.TempFile" );
            XTempFile xTempFile = (XTempFile) UnoRuntime.queryInterface ( XTempFile.class,
                    oTempFile );
            sResult = xTempFile.getUri ();
            return sResult;
        }
        catch ( Exception e )
        {
            Error ( "Exception: " + e );
            return null;
        }
    }
    
    public boolean FillTempFile ( String sURL, XMultiServiceFactory xMSF )
    {
        if ( sURL.length () == 0 || xMSF == null )
        {
            Error ( "Wrong parameters are provided." );
            return false;
        }
        try
        {
            Object oTempAccess = xMSF.createInstance (
                    "com.sun.star.ucb.SimpleFileAccess" );
            XSimpleFileAccess xTempAccess = (XSimpleFileAccess)UnoRuntime.
                    queryInterface ( XSimpleFileAccess.class, oTempAccess );
            XOutputStream xTempOut = xTempAccess.openFileWrite ( sURL );
            if ( xTempOut != null )
            {
                byte pBytes[] = new byte [pBytesCount];
                Random oRandom = new Random ();
                oRandom.nextBytes ( pBytes );
                xTempOut.writeBytes ( pBytes );
                xTempOut.closeOutput ();
            }
        }
        catch ( Exception e )
        {
            Error ( "Exception: " + e );
            KillFile ( sURL, xMSF );
            return false;
        }
        return true;
    }
    
    public void KillFile ( String sURL, XMultiServiceFactory xMSF )
    {
        if ( xMSF == null )
        {
            Error ( "Wrong parameters are provided." );
        }
        try
        {
            Object oTempAccess = xMSF.createInstance (
                    "com.sun.star.ucb.SimpleFileAccess" );
            XSimpleFileAccess xTempAccess = (XSimpleFileAccess)UnoRuntime.queryInterface (
                    XSimpleFileAccess.class, oTempAccess );
            xTempAccess.kill ( sURL );
        }
        catch ( Exception e )
        {
            Error ( "Exception: " + e );
        }
        
        
    }
    
    /*
    public XTempFile GetNewFilledTempStream_Impl () {
     
    }*/
    
    public void Error ( String sError )
    {
        m_aLogWriter.println ( m_sTestPrefix + "Error: " + sError );
    }
    
    public void Message ( String sMessage )
    {
        m_aLogWriter.println ( m_sTestPrefix + sMessage );
    }
}

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to