12176 attach fsfiles (rebased onto develop)



This is the same as gh-2503 but rebased onto develop.

----

See: https://trac.openmicroscopy.org.uk/ome/ticket/12176

This PR begins the work of enabling the conversion of pre-OMERO5 attached original files into OMERO5 filesets. The `test_reimport.py` integration tests performs all the steps necessary to perform such a transformation. In order to clean up after the swap, a new command `omero.cmd.ImageBinariesRequest` (name suggestions welcome) was added which for the first time allows for deleting /OMERO/Pixels files (incl. Pyramids) without needing to delete the entire object.

In order to make better use of some existing methods, this PR also refactors:
 * `BasicACLVoter` which will hopefully alleviate some of the `DUMMY` exceptions we've seen on jenkins
 * `getManagedRepository` logic into `omero.client`
 * `write_stream` logic into `omero.client`

Initial "testing" needed is an API review of `test_reimport` for possible inclusion into `5.0.2`. All integration tests should continue to pass. A next step for this PR is likely to include use of the new command into `fs.py`, though that may depend on whether or not the logic in `test_reimport.py` becomes an OMERO user script or something else.

                    
I'm getting this FAIL consistently:
```
collecting ... collected 1 items
test/integration/test_reimport.py:212: TestReimportArchivedFiles.testConvertSynthetic FAILED
=================================== FAILURES ===================================
________________ TestReimportArchivedFiles.testConvertSynthetic ________________
self = <test.integration.test_reimport.TestReimportArchivedFiles object at 0x10cadb290>
    @pytestmark
    def testConvertSynthetic(self):
        """
            Convert a pre-FS file to FS
            using a README.txt as the first
            in the list.
            """
        readme_path = create_path()
        readme_path.write_text(
            """
                This file has been inserted into the
                fileset in order to prevent import.
                It can be safely deleted.
                """)
        readme_obj = self.client.upload(readme_path,
>                                       name="README.txt")
test/integration/test_reimport.py:227: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
self = <omero.clients.BaseClient object at 0x10e639c50>
filename = path(u'/Users/cblackburn/omero/tmp/omero_cblackburn/8504/omero8yhwQT.tmp')
name = 'README.txt', path = None, type = None, ofile = None, block_size = 1024
    def upload(self, filename, name = None, path = None,
               type = None, ofile = None, block_size = 1024):
        """
            Utility method to upload a file to the server.
            """
        if not self.__sf:
            raise omero.ClientError("No session. Use createSession first.")
        import os, types
        if not filename or not isinstance(filename, types.StringType):
>           raise omero.ClientError("Non-null filename must be provided")
E           ClientError: Non-null filename must be provided
target/omero/clients.py:727: ClientError
 generated xml file: /Users/cblackburn/Work/repos/ome/components/tools/OmeroPy/target/reports/junit-results.xml 
=========================== 1 failed in 4.08 seconds ===========================
```