public SharedFileSystem(UniqueIndexObjectDictionary <ShareObject> shareObjects, /*IPermissions permissions, */ RootShareDirectory[] rootShareDirectories)
        {
            this.shareObjects = shareObjects;
            //this.permissions = permissions;

            this.rootShareDirectories = rootShareDirectories;

            shareObjectsByLocalPath = new Dictionary <String, ShareObject>();


            this.rootShareDirectoryObjects = new DirectoryShareObject[rootShareDirectories.Length];
            for (int i = 0; i < rootShareDirectoryObjects.Length; i++)
            {
                RootShareDirectory rootShareDirectory = rootShareDirectories[i];
                rootShareDirectoryObjects[i] = new DirectoryShareObject(
                    rootShareDirectory.shareObject.localPathAndName,
                    rootShareDirectory.shareObject.name,
                    rootShareDirectory.shareObject.permissions);
            }

            /*
             * for (int i = 0; i < rootShareDirectories.Length; i++)
             * {
             *  RootShareDirectory rootShareDirectory = rootShareDirectories[i];
             *  ShareObject shareObject = CreateNewShareObject(FileType.Directory, rootShareDirectory.localShareDirectory, rootShareDirectory.shareName);
             *  if (shareObject == null)
             *  {
             *      throw new DirectoryNotFoundException(String.Format(
             *          "You are trying to share local directory '{0}', but it either does not exist or is not a directory", rootShareDirectory.localShareDirectory));
             *  }
             *  rootShareDirectory.shareObject = shareObject;
             * }
             */
        }
        static void Main(String[] args)
        {
            //NfsServerLog.stopwatchTicksBase = Stopwatch.GetTimestamp();

            RemoteDataServerProgramOptions options = new RemoteDataServerProgramOptions();
            List <String> nonOptionArguments       = options.Parse(args);

            if (nonOptionArguments.Count < 2)
            {
                options.ErrorAndUsage("Expected at least 2 non-option arguments but got '{0}'", nonOptionArguments.Count);
                return;
            }
            if (nonOptionArguments.Count % 2 == 1)
            {
                options.ErrorAndUsage("Expected an even number of non-option arguments but got {0}", nonOptionArguments.Count);
            }

            UniqueIndexObjectDictionary <ShareObject> shareObjects = new UniqueIndexObjectDictionary <ShareObject>(
                512, 512, 4096, 1024);

            RootShareDirectory[] rootShareDirectories = new RootShareDirectory[nonOptionArguments.Count / 2];
            for (int i = 0; i < rootShareDirectories.Length; i++)
            {
                String localPathAndName = nonOptionArguments[2 * i];
                String remoteShareName  = nonOptionArguments[2 * i + 1];

                DirectoryShareObject directoryShareObject = new DirectoryShareObject(localPathAndName, remoteShareName, null);
                UInt32 id = shareObjects.Add(directoryShareObject);
                directoryShareObject.id = id;

                rootShareDirectories[i] = new RootShareDirectory(directoryShareObject);
            }

            //
            // Options not exposed via command line yet
            //
            Int32 mountListenPort = 59733;
            Int32 backlog         = 4;

            UInt32 readSizeMax = 65536;
            UInt32 suggestedReadSizeMultiple = 4096;

            //
            // Listen IP Address
            //
            IPAddress listenIPAddress = options.listenIPAddress.ArgValue;

            //
            // Npc Server
            //
            IPEndPoint npcServerEndPoint = !options.npcListenPort.set ? null :
                                           new IPEndPoint(listenIPAddress, options.npcListenPort.ArgValue);

            //
            // Logging Options
            //

            /*
             * TextWriter selectServerEventsLog = null;
             * if (options.logLevel.ArgValue != LogLevel.None)
             * {
             *  TextWriter logWriter;
             *  if (options.logFile.set)
             *  {
             *      logWriter = new StreamWriter(new FileStream(options.logFile.ArgValue, FileMode.Create, FileAccess.Write, FileShare.Read));
             *  }
             *  else
             *  {
             *      logWriter = Console.Out;
             *  }
             *
             *  NfsServerLog.sharedFileSystemLogger = (options.logLevel.ArgValue >= LogLevel.Info) ? logWriter : null;
             *  NfsServerLog.rpcCallLogger = (options.logLevel.ArgValue >= LogLevel.Info) ? logWriter : null;
             *  NfsServerLog.warningLogger = (options.logLevel.ArgValue >= LogLevel.Warning) ? logWriter : null;
             *  NfsServerLog.npcEventsLogger = (options.logLevel.ArgValue >= LogLevel.Info) ? logWriter : null;
             *
             *  RpcPerformanceLog.rpcMessageSerializationLogger = (options.logLevel.ArgValue >= LogLevel.Info) ? logWriter : null;
             *
             *  selectServerEventsLog = (options.logLevel.ArgValue >= LogLevel.All) ? logWriter : null;
             * }
             */

            //
            // Permissions
            //
            //ModeFlags defaultDirectoryPermissions =
            //    ModeFlags.OtherExecute | ModeFlags.OtherWrite | ModeFlags.OtherRead |
            //    ModeFlags.GroupExecute | ModeFlags.GroupWrite | ModeFlags.GroupRead |
            //    ModeFlags.OwnerExecute | ModeFlags.OwnerWrite | ModeFlags.OwnerRead;
            /*ModeFlags.SaveSwappedText | ModeFlags.SetUidOnExec | ModeFlags.SetGidOnExec;*/
            //ModeFlags defaultFilePermissions =
            //    ModeFlags.OtherExecute | ModeFlags.OtherWrite | ModeFlags.OtherRead |
            //    ModeFlags.GroupExecute | ModeFlags.GroupWrite | ModeFlags.GroupRead |
            //    ModeFlags.OwnerExecute | ModeFlags.OwnerWrite | ModeFlags.OwnerRead;
            /*ModeFlags.SaveSwappedText | ModeFlags.SetUidOnExec | ModeFlags.SetGidOnExec;*/
            //IPermissions permissions = new ConstantPermissions(defaultDirectoryPermissions, defaultFilePermissions);



            SharedFileSystem sharedFileSystem = new SharedFileSystem(shareObjects, /*permissions, */ rootShareDirectories);

            Buf sendBuffer = new Buf(4096, 1024);

            RemoteDataServer remoteDataServer = new RemoteDataServer(sharedFileSystem, sendBuffer);

            //
            // Create Endpoints
            //

            SelectServer selectServer = new SelectServer(false, new Buf(4096, 4096));

            //this.serverStartTimeStopwatchTicks = Stopwatch.GetTimestamp();

            {
                if (listenIPAddress == null)
                {
                    listenIPAddress = IPAddress.Any;
                }
                IPEndPoint remoteDataEndPoint = new IPEndPoint(listenIPAddress, RemoteData.DefaultPort);
                {
                    Socket tcpSocket = new Socket(remoteDataEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                    tcpSocket.Bind(remoteDataEndPoint);
                    tcpSocket.Listen(backlog);
                    selectServer.control.AddReceiveSocket(tcpSocket, remoteDataServer.AcceptCallback);
                }
                {
                    Socket udpSocket = new Socket(remoteDataEndPoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
                    udpSocket.Bind(remoteDataEndPoint);
                    selectServer.control.AddReceiveSocket(udpSocket, remoteDataServer.DatagramHandler);
                }
            }



            /*
             * if (npcServerEndPoint != null)
             * {
             #if !WindowsCE
             *  Nfs3Server.NfsServerManager nfsServerManager = new Nfs3Server.NfsServerManager(nfsServer);
             *  NpcReflector reflector = new NpcReflector(
             *      new NpcExecutionObject(nfsServerManager, "Nfs3ServerManager", null, null),
             *      new NpcExecutionObject(nfsServer, "Nfs3Server", null, null),
             *      new NpcExecutionObject(portMapServer, "Portmap2Server", null, null),
             *      new NpcExecutionObject(mountServer, "Mount1And3Server", null, null)
             *      );
             *  tcpListeners.Add(new TcpSelectListener(npcServerEndPoint, 32, new NpcStreamSelectServerCallback(
             *      NpcCallback.Instance, reflector, new DefaultNpcHtmlGenerator("NfsServer", reflector))));
             #endif
             * }
             */

            selectServer.Run();
        }