public void StreamStartHandle(XmppStream xmppStream, Stream stream, XmppHandlerContext context)
		{
			var streamHeader = new StringBuilder();
			streamHeader.AppendLine("<?xml version='1.0' encoding='UTF-8'?>");
			streamHeader.AppendFormat("<stream:{0} xmlns:{0}='{1}' xmlns='{2}' from='{3}' id='{4}' version='1.0'>",
				Uri.PREFIX, Uri.STREAM, Uri.CLIENT, stream.To, xmppStream.Id);
			context.Sender.SendTo(xmppStream, streamHeader.ToString());

			var features = new Features();
			features.Prefix = Uri.PREFIX;
			if (xmppStream.Authenticated)
			{
				features.AddChild(new Bind());
				features.AddChild(new Core.protocol.iq.session.Session());
			}
			else
			{
				features.Mechanisms = new Mechanisms();
                var listener = (BoshXmppListener)(context.XmppGateway.GetXmppListener("Bosh Listener"));
                var storage = new DbLdapSettingsStore();
                storage.GetLdapSettings(xmppStream.Domain);
                if (!storage.EnableLdapAuthentication || listener.GetXmppConnection(xmppStream.ConnectionId) != null)
                {
                    features.Mechanisms.AddChild(new Mechanism(MechanismType.DIGEST_MD5));
                }
                else
                {
                    features.Mechanisms.AddChild(new Mechanism(MechanismType.PLAIN));
                }
				features.Mechanisms.AddChild(new Element("required"));
				features.Register = new Register();
			}
			streamHeader.Append(features.ToString());
			context.Sender.SendTo(xmppStream, features);
		}
        private void ProcessAuth(XmppStream stream, Auth auth, XmppHandlerContext context)
        {
            AuthData authStep;
            lock (authData)
            {
                authData.TryGetValue(stream.Id, out authStep);
            }

            if (auth.MechanismType == MechanismType.DIGEST_MD5)
            {
                if (authStep != null)
                {
                    context.Sender.SendToAndClose(stream, XmppFailureError.TemporaryAuthFailure);
                }
                else
                {
                    lock (authData)
                    {
                        authData[stream.Id] = new AuthData();
                    }
                    var challenge = GetChallenge(stream.Domain);
                    context.Sender.SendTo(stream, challenge);
                }
            }
            else if (auth.MechanismType == MechanismType.PLAIN)
            {
                if (auth.TextBase64 == null)
                {
                    context.Sender.SendToAndClose(stream, XmppFailureError.TemporaryAuthFailure);
                }
                else
                {
                    string[] array = auth.TextBase64.Split('\0');
                    if (array.Length == 3)
                    {
                        string userName = array[1];
                        string password = array[2];
                        var storage = new DbLdapSettingsStore();
                        storage.GetLdapSettings(stream.Domain);
                        User user = context.UserManager.GetUser(new Jid(userName, stream.Domain, null));
                        if (user != null)
                        {
                            if (user.Sid != null)
                            {
                                var accountName = storage.getAccountNameBySid(user.Sid);
                                if (accountName != null && storage.CheckCredentials(accountName, password))
                                {
                                    // ldap user
                                    lock (authData)
                                    {
                                        authData[stream.Id] = new AuthData(true);
                                        authData[stream.Id].UserName = userName;
                                        authData[stream.Id].IsAuth = true;
                                    }
                                }
                            }
                            else if (user.Password == password)
                            {
                                // usual user
                                lock (authData)
                                {
                                    authData[stream.Id] = new AuthData(true);
                                    authData[stream.Id].UserName = userName;
                                    authData[stream.Id].IsAuth = true;
                                }
                            }
                        }
                    }
                    lock (authData)
                    {
                        if (!authData.ContainsKey(stream.Id))
                        {
                            authData[stream.Id] = new AuthData(true);
                        }
                    }
                    context.Sender.SendTo(stream, new Challenge());
                }
            }
            else
            {
                context.Sender.SendToAndClose(stream, XmppFailureError.InvalidMechanism);
            }
        }