package BMActivityStream;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.Vector;
import java.util.Enumeration;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;

import org.apache.commons.io.IOUtils;

import java.util.Iterator;
import java.util.Set;
import com.sun.net.httpserver.Headers;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;

import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.URLDecoder;
import java.net.URI;

import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
import com.sun.net.httpserver.Filter;
import com.sun.net.httpserver.HttpContext;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import java.io.ByteArrayInputStream;

import org.apache.commons.codec.binary.Base64;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.entity.StringEntity;
import org.apache.http.util.EntityUtils;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;

import org.json.simple.parser.ContainerFactory;
import org.json.simple.parser.ContentHandler;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

import java.io.*;
import java.util.Hashtable;
import javax.mail.*;
import javax.mail.internet.*;
import javax.mail.util.*;
import javax.activation.*;


public class BMActivityStream {

private static ActivityStreamdb db = null;

	public static void main(String[] args) throws Exception
	{
	
	        try {
			db = new ActivityStreamdb("db_file_activitystream");
		} catch (Exception ex1) {
			ex1.printStackTrace();
			return;                   // bye bye
		}
	
		try {	
			System.out.println("Creating database entries");
			db.update("CREATE TABLE bm_table ( msgid VARCHAR(64), address VARCHAR(38), application VARCHAR(64), message LONGVARCHAR, dtstamp TIMESTAMP)");
			System.out.println("Created bm_table");
		} catch (SQLException ex2) {
			System.out.println("Table bm_table in place");
		}
		try {
			db.update("CREATE TABLE bm_mail ( msgid VARCHAR(64), ackdata VARCHAR(64), read BOOLEAN, folder VARCHAR(64), toaddress VARCHAR(38), fromaddress VARCHAR(38), subject LONGVARCHAR, message LONGVARCHAR, encodingtype INTEGER, dtstamp TIMESTAMP)");
			System.out.println("Created bm_mail");
		} catch (SQLException ex2) {
			System.out.println("Table bm_mail in place");
		}
		try {
			db.update("CREATE TABLE bm_mail_folders ( folder VARCHAR(64))");
			System.out.println("Created bm_mail_folders");
			try {
				String INSERT_RECORD = "INSERT INTO bm_mail_folders(folder) VALUES(?)";
				PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
				pstmt.setString(1, "Inbox");
				int i = pstmt.executeUpdate();
				if (i == -1) {
					System.out.println("db error : " );
				}
				pstmt.close();
			} catch (SQLException ex3) {
				ex3.printStackTrace();
			}
			try {
				String INSERT_RECORD = "INSERT INTO bm_mail_folders(folder) VALUES(?)";
				PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
				pstmt.setString(1, "Sent");
				int i = pstmt.executeUpdate();
				if (i == -1) {
					System.out.println("db error : " );
				}
				pstmt.close();
			} catch (SQLException ex3) {
				ex3.printStackTrace();
			}
			try {
				String INSERT_RECORD = "INSERT INTO bm_mail_folders(folder) VALUES(?)";
				PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
				pstmt.setString(1, "Drafts");
				int i = pstmt.executeUpdate();
				if (i == -1) {
					System.out.println("db error : " );
				}
				pstmt.close();
			} catch (SQLException ex3) {
				ex3.printStackTrace();
			}
			try {
				String INSERT_RECORD = "INSERT INTO bm_mail_folders(folder) VALUES(?)";
				PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
				pstmt.setString(1, "Spam");
				int i = pstmt.executeUpdate();
				if (i == -1) {
					System.out.println("db error : " );
				}
				pstmt.close();
			} catch (SQLException ex3) {
				ex3.printStackTrace();
			}
			try {
				String INSERT_RECORD = "INSERT INTO bm_mail_folders(folder) VALUES(?)";
				PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
				pstmt.setString(1, "Trash");
				int i = pstmt.executeUpdate();
				if (i == -1) {
					System.out.println("db error : " );
				}
				pstmt.close();
			} catch (SQLException ex3) {
				ex3.printStackTrace();
			}


		} catch (SQLException ex2) {
			System.out.println("Table bm_mail_folders in place");
		}
		try {
			db.update("CREATE TABLE bm_profiles ( address VARCHAR(38), follower BOOLEAN, follower_msgid VARCHAR(64), following BOOLEAN, following_msgid VARCHAR(64), label VARCHAR(128), notes LONGVARCHAR, dtstamp TIMESTAMP)");
			System.out.println("Created bm_profiles"); 
		} catch (SQLException ex2) {
			System.out.println("Table bm_profiles in place");
		}
		try {
			db.update("CREATE TABLE bm_profiles_lists ( address VARCHAR(38), list LONGVARCHAR)");
			System.out.println("Created bm_profiles_lists");
		} catch (SQLException ex2) {
			System.out.println("Table bm_profiles_lists in place");
		}
		try {
			db.update("CREATE TABLE bm_alerts ( msgid VARCHAR(64), message LONGVARCHAR, dtstamp TIMESTAMP)");
			System.out.println("Created bm_alerts");
		} catch (SQLException ex2) {
			System.out.println("Table bm_alerts in place");
		}
		try {
			db.update("CREATE TABLE bm_groups ( address VARCHAR(38), label LONGVARCHAR, know_members VARCHAR(38))");
			System.out.println("Created bm_groups");
		} catch (SQLException ex2) {
			System.out.println("Table bm_groups in place");
		}
		try {
			db.update("CREATE TABLE bm_lastclick ( wpage VARCHAR(64), dtstamp TIMESTAMP)");
			System.out.println("Created bm_lastclick");
			try {
				String INSERT_RECORD = "INSERT INTO bm_lastclick(wpage,dtstamp) VALUES(?,?)";
				PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
				pstmt.setString(1, "MESSAGES");
				java.sql.Timestamp  sqlDate = new java.sql.Timestamp(new java.util.Date().getTime());
				pstmt.setTimestamp(2, sqlDate);
				int i = pstmt.executeUpdate();
				if (i == -1) {
					System.out.println("db error : " );
				}
				pstmt.close();
			} catch (SQLException ex3) {
				ex3.printStackTrace();
			}
			try {
				String INSERT_RECORD = "INSERT INTO bm_lastclick(wpage,dtstamp) VALUES(?,?)";
				PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
				pstmt.setString(1, "FOLLOWERS");
				java.sql.Timestamp  sqlDate = new java.sql.Timestamp(new java.util.Date().getTime());
				pstmt.setTimestamp(2, sqlDate);
				int i = pstmt.executeUpdate();
				if (i == -1) {
					System.out.println("db error : " );
				}
				pstmt.close();
			} catch (SQLException ex3) {
				ex3.printStackTrace();
			}
			try {
				String INSERT_RECORD = "INSERT INTO bm_lastclick(wpage,dtstamp) VALUES(?,?)";
				PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
				pstmt.setString(1, "ALERTS");
				java.sql.Timestamp  sqlDate = new java.sql.Timestamp(new java.util.Date().getTime());
				pstmt.setTimestamp(2, sqlDate);
				int i = pstmt.executeUpdate();
				if (i == -1) {
					System.out.println("db error : " );
				}
				pstmt.close();
			} catch (SQLException ex3) {
				ex3.printStackTrace();
			}

		} catch (SQLException ex2) {
			System.out.println("Table bm_lastclick in place");
		}
		try {
			db.update("CREATE TABLE bm_settings ( setting LONGVARCHAR, value LONGVARCHAR)");
			System.out.println("Created bm_settings");
			try {
				String INSERT_RECORD = "INSERT INTO bm_settings(setting,value) VALUES(?,?)";
				PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
				pstmt.setString(1, "bmapi_ip");
				pstmt.setString(2, "localhost");
				int i = pstmt.executeUpdate();
				if (i == -1) {
					System.out.println("db error : " );
				}
				pstmt.close();
			} catch (SQLException ex3) {
				ex3.printStackTrace();
			}
			try {
				String INSERT_RECORD = "INSERT INTO bm_settings(setting,value) VALUES(?,?)";
				PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
				pstmt.setString(1, "bmapi_port");
				pstmt.setString(2, "8442");
				int i = pstmt.executeUpdate();
				if (i == -1) {
					System.out.println("db error : " );
				}
				pstmt.close();
			} catch (SQLException ex3) {
				ex3.printStackTrace();
			}
			try {
				String INSERT_RECORD = "INSERT INTO bm_settings(setting,value) VALUES(?,?)";
				PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
				pstmt.setString(1, "bmapi_user");
				pstmt.setString(2, "default");
				int i = pstmt.executeUpdate();
				if (i == -1) {
					System.out.println("db error : " );
				}
				pstmt.close();
			} catch (SQLException ex3) {
				ex3.printStackTrace();
			}
			try {
				String INSERT_RECORD = "INSERT INTO bm_settings(setting,value) VALUES(?,?)";
				PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
				pstmt.setString(1, "bmapi_password");
				pstmt.setString(2, "default");
				int i = pstmt.executeUpdate();
				if (i == -1) {
					System.out.println("db error : " );
				}
				pstmt.close();
			} catch (SQLException ex3) {
				ex3.printStackTrace();
			}
			try {
				String INSERT_RECORD = "INSERT INTO bm_settings(setting,value) VALUES(?,?)";
				PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
				pstmt.setString(1, "bmapi_client");
				pstmt.setString(2, "false");
				int i = pstmt.executeUpdate();
				if (i == -1) {
					System.out.println("db error : " );
				}
				pstmt.close();
			} catch (SQLException ex3) {
				ex3.printStackTrace();
			}

		} catch (SQLException ex2) {
			System.out.println("Table bm_settings in place");
		}

	        HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0);
		HttpContext context = server.createContext("/", new MainHandler(db));
		context.getFilters().add(new ParameterFilter());
		context = server.createContext("/alerts", new AlertsHandler(db));
		context.getFilters().add(new ParameterFilter());
		context = server.createContext("/followers", new ProfilesHandler(db));
		context.getFilters().add(new ParameterFilter());
		context = server.createContext("/message", new MessageHandler(db));
		context.getFilters().add(new ParameterFilter());
		context = server.createContext("/messages", new MessagesHandler(db));
		context.getFilters().add(new ParameterFilter());
		context = server.createContext("/profile", new ProfileHandler(db));
		context.getFilters().add(new ParameterFilter());
		context = server.createContext("/send", new SendHandler(db));
		context.getFilters().add(new ParameterFilter());
		context = server.createContext("/send_message", new SendMessageHandler(db));
		context.getFilters().add(new ParameterFilter());
		context = server.createContext("/settings", new SettingsHandler(db));
		context.getFilters().add(new ParameterFilter());
		context = server.createContext("/logout", new LogoutHandler(db, server));
		context.getFilters().add(new ParameterFilter());

		server.setExecutor(null); // creates a default executor
		System.out.println("HttpServer started");
		server.start();
	
	}
	
	static class MainHandler implements HttpHandler
	{
		private ActivityStreamdb db = null;
		
		public MainHandler(ActivityStreamdb db) {
			this.db = db;
		}
		
	        public void handle(HttpExchange t) throws IOException {
		
	        	String response = "";
			String application = "news";
			String mid = "";
		
			processMessages processor = new processMessages(db);
			processor.process();

			HTMLBuilder html = new HTMLBuilder();
			html.appendHTMLHead();
			html.appendHTMLStyle();
			html.appendHTMLScript();
			html.appendHTMLHeadEndNews();
			html.appendNAVBar();
			html.appendMainLeftMenu();
			html.appendEndDiv();
			html.appendMainStart();
			
			@SuppressWarnings("unchecked")
			Map<String, Object> params = (Map<String, Object>)t.getAttribute("parameters");

			if (params.containsKey("application"))
			{
				application = (String)params.get("application");
			}
			if (params.containsKey("msgid"))
			{
				mid = (String)params.get("msgid");
			}

			NewsPostForm postform = new NewsPostForm();
			if (mid.equals(""))
			{
				response = response + postform.getNewsPostForm();
			}

			int offset = 0;
			int maxPages = 1;
			int page = 1;
			if (mid.equals(""))
			{
				int count = 0;
				String csql = "SELECT COUNT(*) AS rowcount FROM bm_table WHERE application=?";
				try {
					PreparedStatement pstmt = db.conn.prepareStatement(csql);
					pstmt.setString(1, application);
					ResultSet rs = pstmt.executeQuery();
					rs.next();
					count = rs.getInt(1);
					pstmt.close();	
				} catch (SQLException ex3) {
					ex3.printStackTrace();
				}
				maxPages = (count/100);
				if (maxPages*100 < count)
				{
					maxPages = maxPages + 1;
				}
				page = 1;
				if (params.containsKey("page"))
				{
					String spage = (String)params.get("page");
					page = Integer.parseInt(spage);
				}
				offset = (page*100) - 100;
			}
			if (application.equals("news"))
			{
				String like = "";
				String addressFrom = "";
				String target = "";
				String inReplyTo = "";
				
				if (params.containsKey("like"))
				{
					like = (String)params.get("like");
					addressFrom = (String)params.get("address");
					target = (String)params.get("target");
					inReplyTo = (String)params.get("inReplyTo");
					Node activity = null;
					try {
						String query = "SELECT message FROM bm_table WHERE msgid='" + target + "'";
						ResultSet dbq = db.query(query);
						Object o = null;
						for (; dbq.next(); ) {
							o = dbq.getObject(1);
							String message = o.toString();
							try {
								DocumentBuilderFactory dbFactory2 = DocumentBuilderFactory.newInstance();
								DocumentBuilder dBuilder2 = dbFactory2.newDocumentBuilder();
								Document doc2 = dBuilder2.parse(new ByteArrayInputStream(message.getBytes()));
								doc2.getDocumentElement().normalize();
								activity = doc2.getElementsByTagName("activity").item(0);
   							} catch (Exception e) {
								e.printStackTrace();
							}
						}
						db.st.close();
					} catch (SQLException ex3) {
						ex3.printStackTrace();
					} 	
						
					Like liker = new Like(activity, addressFrom, target, inReplyTo);
					liker.like();
				}
				
				InputStream is = t.getRequestBody();
								
				if (t.getRequestMethod().equalsIgnoreCase("POST"))
				{

					stream2File fstream = new stream2File();
					File tmpfile = fstream.getstream2file(is);

					try {
						DataSource ds = new FileDataSource(tmpfile);
						FormdataMultipart forminput = new FormdataMultipart(ds);
						Hashtable paramsa = forminput.getParameters();
						if (paramsa.containsKey("comment"))
						{
							String[] commenta = (String[])paramsa.get("comment");
							String comment = commenta[0];
							comment = "<![CDATA[" + comment + "]]>";
							String[] addressFroma = (String[])paramsa.get("address");
							addressFrom = addressFroma[0];
							String[] targeta = (String[])paramsa.get("targetid");
							target = targeta[0];
							String[] inReplyToa = (String[])paramsa.get("inreplytoid");
							inReplyTo = inReplyToa[0];
							String[] comment_typea = (String[])paramsa.get("comment_type");
							String comment_type = comment_typea[0];
							Node activity = null;
							try {
								String query = "SELECT message FROM bm_table WHERE msgid='" + target + "'";
								ResultSet dbq = db.query(query);
								Object o = null;
								for (; dbq.next(); ) {
									o = dbq.getObject(1);
									String message = o.toString();
									try {
										DocumentBuilderFactory dbFactory2 = DocumentBuilderFactory.newInstance();
										DocumentBuilder dBuilder2 = dbFactory2.newDocumentBuilder();
										Document doc2 = dBuilder2.parse(new ByteArrayInputStream(message.getBytes()));
										doc2.getDocumentElement().normalize();
										activity = doc2.getElementsByTagName("activity").item(0);
   									} catch (Exception e) {
										e.printStackTrace();
									}
								}
								db.st.close();
							} catch (SQLException ex3) {
								ex3.printStackTrace();
							} 
							Comment commenter = new Comment(activity, addressFrom, target, inReplyTo, comment, comment_type);
							commenter.comment();
						}
						if (paramsa.containsKey("share_post"))
						{
							String[] commenta = (String[])paramsa.get("share_post");
							String comment = commenta[0];
							comment = "<![CDATA[" + comment + "]]>";
							ArrayList<String> images = new ArrayList<String>();
							for (int i=0; i< forminput.getCount(); i++)
							{
								BodyPart bodprt = forminput.getBodyPart(i);
								DataHandler blah = bodprt.getDataHandler();
								InputStream is4 = blah.getInputStream();
								String imagein = "data:" + blah.getContentType() + ";base64,";
								base64processor encoded = new base64processor();
								imagein = imagein + encoded.toString(IOUtils.toByteArray(is4));
								images.add(imagein);
							}	
							
							String[] ToAddress = (String[])paramsa.get("To");
							String[] followersa = (String[])paramsa.get("followers");
							String ToAddressType = followersa[0];
							Post poster = new Post(ToAddressType, ToAddress, comment, images);
							poster.post();
						}
									
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			
				try {
					String query = "";
					if (mid.equals(""))
					{
						query = "SELECT msgid, address, message FROM bm_table WHERE application='news' ORDER BY dtstamp DESC LIMIT 100 OFFSET " + Integer.toString(offset) + "";
					} else {
						query = "SELECT msgid, address, message FROM bm_table WHERE application='news' AND msgid='" + mid + "'";
					}
					ResultSet dbq = db.query(query);
					Object o = null;
					for (; dbq.next(); ) {
						o = dbq.getObject(1);
						String msgid = o.toString();
						o = dbq.getObject(2);
						String address = o.toString();
						o = dbq.getObject(3);
						String message = o.toString();
						response = response + "<br><div id='post'><div id='" + msgid + "'><a href='/profile?address=" + address + "'>" + address + "</a><br>";			
						try {
							DocumentBuilderFactory dbFactory2 = DocumentBuilderFactory.newInstance();
							DocumentBuilder dBuilder2 = dbFactory2.newDocumentBuilder();
							Document doc2 = dBuilder2.parse(new ByteArrayInputStream(message.getBytes()));
							doc2.getDocumentElement().normalize();
							NodeList nList2 = doc2.getElementsByTagName("activity");
							String content = "";
							String image = "";
							int likes = 0;
							String likers = "";
							int commentnumber = 0;
							ArrayList<String> recipients = new ArrayList<String>();
							ArrayList<String> commenters = new ArrayList<String>();
							ArrayList<String> contents = new ArrayList<String>();
							for (int temp2 = 0; temp2 < nList2.getLength(); temp2++)
							{
								Node nNode2 = nList2.item(temp2);
								if (nNode2.getNodeType() == Node.ELEMENT_NODE)
								{
									Element eElement = (Element) nNode2;
									NodeList toNodeList = eElement.getElementsByTagName("to");
									for (int temp3 = 0; temp3 < toNodeList.getLength(); temp3++)
									{
										Node toCNode = toNodeList.item(temp3);
										Element toE = (Element) toCNode;
										NodeList toCNodeList = toE.getChildNodes();
										for (int temp4 = 0; temp4 < toCNodeList.getLength(); temp4++)
										{
											Node cnode = toCNodeList.item(temp4);
											if (cnode.getNodeName().equals("id"))
											{
												recipients.add(cnode.getTextContent());
											}
										}
									}
									NodeList objectNodeList = eElement.getElementsByTagName("object");
									for (int temp3 = 0; temp3 < objectNodeList.getLength(); temp3++)
									{
										Node objectCNode = objectNodeList.item(temp3);
										if (objectCNode.getNodeType() == Node.ELEMENT_NODE)
										{
											Element cElement = (Element) objectCNode;
											NodeList objectCNodeList = cElement.getChildNodes();
											for (int temp4=0; temp4<objectCNodeList.getLength(); temp4++)
											{
												Node cnode = objectCNodeList.item(temp4);
												if (cnode.getNodeName().equals("content"))
												{
													content = cElement.getElementsByTagName("content").item(temp3).getTextContent();
													content = content.replace("&", "&");
													content = content.replace("\"", """);
													content = content.replace("<", "<");
													content = content.replace(">", ">");
													response = response + "<pre>" + content + "</pre>";
												}
											}
											for (int temp4=0; temp4<objectCNodeList.getLength(); temp4++)
											{
												Node cnode = objectCNodeList.item(temp4);
												if (cnode.getNodeName().equals("image"))
												{
													image = cElement.getElementsByTagName("image").item(temp3).getTextContent();
													if (image.length() > 0)
													{
														response = response + "<div id='newsimage'><img src=\"" + image + "\"></div><br>";
													}
												}
											}
											for (int temp4=0; temp4<objectCNodeList.getLength(); temp4++)
											{
												Node cnode = objectCNodeList.item(temp4);
												if (cnode.getNodeName().equals("likes"))
												{
													likes = Integer.parseInt(cElement.getElementsByTagName("totalItems").item(0).getTextContent());
													Node itemsN = cElement.getElementsByTagName("items").item(0);
													Element itemsE = (Element) itemsN;
													NodeList itemNL = itemsE.getChildNodes();
													for (int temp5=0; temp5 < itemNL.getLength(); temp5++)
													{
														Node itemN = itemNL.item(temp5);
														Element itemE = (Element) itemN;
														Node actorN = itemE.getElementsByTagName("actor").item(0);
														Element actorE = (Element) actorN;
														likers = likers + actorE.getElementsByTagName("id").item(0).getTextContent() + "&#13;";
													}
												}
											}
											for (int temp4=0; temp4<objectCNodeList.getLength(); temp4++)
											{
												Node cnode = objectCNodeList.item(temp4);
												if (cnode.getNodeName().equals("comments"))
												{
													commentnumber = Integer.parseInt(cElement.getElementsByTagName("totalItems").item(0).getTextContent());
												}
											}
											response = response + "<a title='Liked by:&#13;" + likers + "' href='/?application=" + application + "&page=" + page + "&like=y&address=" + address + "&target=" + msgid + "&inReplyTo=" + msgid + "'>Like (" + likes + ")</a> <a href='javascript:movecomment_form(\"" + msgid + "\",\"form" + msgid + "\",\"comment_form" + msgid + "\",\"" + address + "\",\"" + msgid + "\",\"" + msgid + "\")'>Comment (" + commentnumber + ")</a>";
											for (int temp4=0; temp4<objectCNodeList.getLength(); temp4++)
											{
												Node cnode = objectCNodeList.item(temp4);
												if (cnode.getNodeName().equals("comments"))
												{
													commentnumber = Integer.parseInt(cElement.getElementsByTagName("totalItems").item(0).getTextContent());
													Node itemsN = cElement.getElementsByTagName("items").item(0);
													Element itemsE = (Element) itemsN;
													NodeList itemNL = itemsE.getChildNodes();
													for (int temp5=0; temp5 < itemNL.getLength(); temp5++)
													{
														int clikes = 0;
														String clikers = "";
														String commentID = "";
														Node itemN = itemNL.item(temp5);
														Element itemE = (Element) itemN;
														NodeList itemCNL = itemE.getChildNodes();
														for (int temp6 = 0; temp6<itemCNL.getLength(); temp6++)
														{
															Node itemCNode = itemCNL.item(temp6);
															if (itemCNode.getNodeName().equals("id"))
															{ 
																commentID = itemCNode.getTextContent();
															}
														}
														for (int temp6 = 0; temp6<itemCNL.getLength(); temp6++)
														{
															Node itemCNode = itemCNL.item(temp6);
															if (itemCNode.getNodeName().equals("actor"))
															{ 
																Node actorN = itemE.getElementsByTagName("actor").item(0);
																Element actorE = (Element) actorN;
																String commenter = actorE.getElementsByTagName("id").item(0).getTextContent();
																response = response + "<div id='comment'><div id='" + commentID +"'><a href='/profile?address=" + commenter + "'>" + commenter + "</a><br>";
															}
														}
														for (int temp6 = 0; temp6<itemCNL.getLength(); temp6++)
														{
															Node itemCNode = itemCNL.item(temp6);
															if (itemCNode.getNodeName().equals("content"))
															{
																String contento = itemE.getElementsByTagName("content").item(0).getTextContent();
																response = response + "<pre>" + contento + "</pre>";
															}
														}
														for (int temp6 = 0; temp6<itemCNL.getLength(); temp6++)
														{
															Node itemCNode = itemCNL.item(temp6);
															if (itemCNode.getNodeName().equals("likes"))
															{
																clikes = Integer.parseInt(itemE.getElementsByTagName("totalItems").item(0).getTextContent());
																Node itemsN2 = itemE.getElementsByTagName("items").item(0);
																Element itemsE2 = (Element) itemsN2;
																NodeList itemNL2 = itemsE2.getChildNodes();
																for (int itemno=0; itemno < itemNL2.getLength(); itemno++)
																{
																	Node itemN2 = itemNL2.item(itemno);
																	Element itemE2 = (Element) itemN2;
																	Node actorN = itemE.getElementsByTagName("actor").item(0);
																	Element actorE = (Element) actorN;
																	clikers = clikers + actorE.getElementsByTagName("id").item(0).getTextContent() + "&#13;";
																}
															}
														}
														int commentnumber2 = 0;
														for (int temp6 = 0; temp6<itemCNL.getLength(); temp6++)
														{
															Node itemCNode = itemCNL.item(temp6);
															if (itemCNode.getNodeName().equals("comments"))
															{
																commentnumber2 = Integer.parseInt(itemE.getElementsByTagName("totalItems").item(0).getTextContent());
															}
														}
														response = response + "<a title='Liked by:&#13;" + clikers + "' href='/?application=" + application + "&page=" + page + "&like=y&address=" + address + "&target=" + msgid + "&inReplyTo=" + commentID + "'>Like (" + clikes + ")</a> <a href='javascript:movecomment_form(\"" + commentID + "\",\"form" + msgid + "\",\"comment_form" + msgid + "\",\"" + address + "\",\"" + msgid + "\",\"" + commentID + "\")'>Comment (" + commentnumber2 + ")</a>";
														for (int temp6 = 0; temp6<itemCNL.getLength(); temp6++)
														{
															Node itemCNode = itemCNL.item(temp6);
															if (itemCNode.getNodeName().equals("comments"))
															{
																Node itemsN2 = itemE.getElementsByTagName("items").item(0);
																Element itemsE2 = (Element) itemsN2;
																NodeList itemNL2 = itemsE2.getChildNodes();
																for (int itemno=0; itemno < itemNL2.getLength(); itemno++)
																{
																	Node innode = itemNL2.item(itemno);
																	response = processComment(innode, address, msgid, application, page, response);
																}
															}
														}
														response = response + "</div></div><br>"; 
													}
												}
											}
										}
									}
								}
							}
							response = response + "<div id='form" + msgid + "'><div id='comment_form'><form id='comment_form" + msgid + "' action='/' method='post' enctype='multipart/form-data'>";
							response = response + "<textarea name='comment' style='display:block;width:100%;left-margin:10px;right-margin:10px'></textarea><br>";
							response = response + "<input name='address' type='hidden' value='" + address + "'>";
							response = response + "<input name='targetid' type='hidden' value='" + msgid + "'>";
							response = response + "<input name='inreplytoid' type='hidden' value='" + msgid + "'>";
							response = response + "<input type='submit' value='Comment'>";
							bmasAddresses useraddress = new bmasAddresses();
							String user = useraddress.getChan();
							if ((address.equals(user)) || (recipients.contains(user)))
							{
								response = response + "<select name='comment_type'>";
								response = response + "<option value='Signed'>Signed</option>";
								response = response + "<option value='Anonymous'>Anonymous</option>";
								response = response + "<select>";
							} else {
								response = response + "<input name='comment_type' type='hidden' value='Signed'>";
							}
							response = response + "</form></div></div>";
							response = response + "</div></div>";
   						} catch (Exception e) {
							e.printStackTrace();
						}
					}
					db.st.close();
				} catch (SQLException ex3) {
					ex3.printStackTrace();
				} 
			}
			if (mid.equals(""))
			{

			response = response + "<p style=\"text-align:center\">";
			if (page > 1)
			{
				response = response + "<a href='/?application=" + application + "&page=1'>First</a> ";
				response = response + "<a href='/?application=" + application + "&page=" + (page - 1) + "'>Previous</a> ";
			}
			int opage = page;
			while ((opage <= page + 9) && (opage <= maxPages))
			{
				response = response + "<a href='/?application=" + application + "&page=" + opage + "'>" + opage + "</a> ";
				opage = opage + 1;
			}
			if (page < maxPages)
			{
				response = response + "<a href='/?application=" + application + "&page=" + (page + 1) + "'>Next</a> ";
			}
			response = response + "<a href='/?application=" + application + "&page=" + maxPages +"'>Last</a> ";
			response = response + "</p>";
			}
			html.append(response);
			html.appendEndDiv();
			html.appendEndBody();
				
		        t.sendResponseHeaders(200, html.getHTML().length());
		        OutputStream os = t.getResponseBody();
			os.write(html.getHTML().getBytes());
			os.close();
        	}
				
		public String processComment(Node itemN, String address, String msgid, String application, int page, String response)
		{
			int clikes = 0;
			String clikers = "";
			String commentID = "";
			Element itemE = (Element) itemN;
			NodeList itemCNL = itemE.getChildNodes();
			for (int temp6 = 0; temp6<itemCNL.getLength(); temp6++)
			{
				Node itemCNode = itemCNL.item(temp6);
				if (itemCNode.getNodeName().equals("id"))
				{ 
					commentID = itemCNode.getTextContent();
				}
			}
			for (int temp6 = 0; temp6<itemCNL.getLength(); temp6++)
			{
				Node itemCNode = itemCNL.item(temp6);
				if (itemCNode.getNodeName().equals("actor"))
				{ 
					Node actorN = itemE.getElementsByTagName("actor").item(0);
					Element actorE = (Element) actorN;
					String commenter = actorE.getElementsByTagName("id").item(0).getTextContent();
					response = response + "<div id='comment'><div id='" + commentID +"'><a href='/profile?address=" + commenter + "'>" + commenter + "</a><br>";
				}
			}
			for (int temp6 = 0; temp6<itemCNL.getLength(); temp6++)
			{
				Node itemCNode = itemCNL.item(temp6);
				if (itemCNode.getNodeName().equals("content"))
				{
					String contento = itemE.getElementsByTagName("content").item(0).getTextContent();
					response = response + "<pre>" + contento + "</pre>";
				}
			}
			for (int temp6 = 0; temp6<itemCNL.getLength(); temp6++)
			{
				Node itemCNode = itemCNL.item(temp6);
				if (itemCNode.getNodeName().equals("likes"))
				{
					Node likesN = itemE.getElementsByTagName("likes").item(0);
					Element likesE = (Element) likesN;
					clikes = Integer.parseInt(likesE.getElementsByTagName("totalItems").item(0).getTextContent());
					Node itemsN2 = likesE.getElementsByTagName("items").item(0);
					Element itemsE2 = (Element) itemsN2;
					NodeList itemNL2 = itemsE2.getChildNodes();
					for (int itemno=0; itemno < itemNL2.getLength(); itemno++)
					{
						Node itemN2 = itemNL2.item(itemno);
						Element itemE2 = (Element) itemN2;
						Node actorN = itemE2.getElementsByTagName("actor").item(0);
						Element actorE = (Element) actorN;
						clikers = clikers + actorE.getElementsByTagName("id").item(0).getTextContent() + "&#13;";
					}
				}
			}
			int commentnumber2 = 0;
			for (int temp6 = 0; temp6<itemCNL.getLength(); temp6++)
			{
				Node itemCNode = itemCNL.item(temp6);
				if (itemCNode.getNodeName().equals("comments"))
				{
					Node commentsN2 = itemE.getElementsByTagName("comments").item(0);
					Element commentsE2 = (Element) commentsN2;
					commentnumber2 = Integer.parseInt(commentsE2.getElementsByTagName("totalItems").item(0).getTextContent());
				}
			}
			response = response + "<a title='Liked by:&#13;" + clikers + "' href='/?application=" + application + "&page=" + page + "&like=y&address=" + address + "&target=" + msgid + "&inReplyTo=" + commentID + "'>Like (" + clikes + ")</a> <a href='javascript:movecomment_form(\"" + commentID + "\",\"form" + msgid + "\",\"comment_form" + msgid + "\",\"" + address + "\",\"" + msgid + "\",\"" + commentID + "\")'>Comment (" + commentnumber2 + ")</a>";
			for (int temp6 = 0; temp6<itemCNL.getLength(); temp6++)
			{
				Node itemCNode = itemCNL.item(temp6);
				if (itemCNode.getNodeName().equals("comments"))
				{
					Node commentsN2 = itemE.getElementsByTagName("comments").item(0);
					Element commentsE2 = (Element) commentsN2;
					Node itemsN2 = commentsE2.getElementsByTagName("items").item(0);
					Element itemsE2 = (Element) itemsN2;
					NodeList itemNL2 = itemsE2.getChildNodes();
					for (int itemno=0; itemno < itemNL2.getLength(); itemno++)
					{
						Node itemo = itemNL2.item(itemno);
						response = processComment(itemo, address, msgid, application, page, response);
					}
				}
			}
			response = response + "</div></div><br>";
			return response;
		}
		
	}

	static class AlertsHandler implements HttpHandler
	{
		private ActivityStreamdb db = null;
		
		public AlertsHandler(ActivityStreamdb db) {
			this.db = db;
		}
		
	        public void handle(HttpExchange t) throws IOException {
		
			String response = "";

			processMessages processor = new processMessages(db);
			processor.process();

			try {
				String INSERT_RECORD = "UPDATE bm_lastclick SET dtstamp=? WHERE wpage=?";
				PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
				java.sql.Timestamp  sqlDate = new java.sql.Timestamp(new java.util.Date().getTime());
				pstmt.setTimestamp(1, sqlDate);
				pstmt.setString(2, "ALERTS");
				int i = pstmt.executeUpdate();
				if (i == -1) {
					System.out.println("db error : " );
				}
				pstmt.close();
			} catch (SQLException ex3) {
				ex3.printStackTrace();
			}

			HTMLBuilder html = new HTMLBuilder();
			html.appendDefaultStart();
			html.appendEndDiv();
			html.appendMainStart();

			@SuppressWarnings("unchecked")
			Map<String, Object> params = (Map<String, Object>)t.getAttribute("parameters");

			int offset = 0;
			int maxPages = 1;
			int page = 1;
			int count = 0;
			String csql = "SELECT COUNT(*) AS rowcount FROM bm_alerts";
			try {
				PreparedStatement pstmt = db.conn.prepareStatement(csql);
				ResultSet rs = pstmt.executeQuery();
				rs.next();
				count = rs.getInt(1);
				pstmt.close();	
			} catch (SQLException ex3) {
				ex3.printStackTrace();
			}
			maxPages = (count/100);
			if (maxPages*100 < count)
			{
				maxPages = maxPages + 1;
			}
			page = 1;
			if (params.containsKey("page"))
			{
				String spage = (String)params.get("page");
				page = Integer.parseInt(spage);
			}
			offset = (page*100) - 100;

			try {
				String query = "";
				query = "SELECT msgid, message, dtstamp FROM bm_alerts ORDER BY dtstamp DESC LIMIT 100 OFFSET " + Integer.toString(offset) + "";
				ResultSet dbq = db.query(query);
				Object o = null;
				for (; dbq.next(); ) {
					o = dbq.getObject(1);
					String msgid = o.toString();
					o = dbq.getObject(2);
					String message = o.toString();
					o = dbq.getObject(3);
					String datestamp = o.toString();
					String application = "";
					String query2 = "SELECT application FROM bm_table WHERE msgid='" + msgid +"'";
					ResultSet dbq2 = db.query(query2);
					Object o2 = null;
					for (; dbq2.next(); ) {
						o2 = dbq2.getObject(1);
						application = o2.toString();
					}
					response = response + "<br>";
					response = response + "<a href='/?application=" + application + "&msgid=" + msgid + "'>" + message + "</a> " + datestamp + "<br>";
				}
				db.st.close();
			} catch (SQLException ex3) {
				ex3.printStackTrace();
			} 


			response = response + "<p style=\"text-align:center\">";
			if (page > 1)
			{
				response = response + "<a href='/alerts?page=1'>First</a> ";
				response = response + "<a href='/alerts?page=" + (page - 1) + "'>Previous</a> ";
			}
			int opage = page;
			while ((opage <= page + 9) && (opage <= maxPages))
			{
				response = response + "<a href='/alerts?page=" + opage + "'>" + opage + "</a> ";
				opage = opage + 1;
			}
			if (page < maxPages)
			{
				response = response + "<a href='/alerts?page=" + (page + 1) + "'>Next</a> ";
			}
			response = response + "<a href='/alerts?page=" + maxPages +"'>Last</a> ";
			response = response + "</p>";
			html.append(response);
			html.appendEndDiv();
			html.appendEndBody();
			
		        t.sendResponseHeaders(200, html.getHTML().length());
		        OutputStream os = t.getResponseBody();
			os.write(html.getHTML().getBytes());
			os.close();

		}
	}

	static class LogoutHandler implements HttpHandler
	{
		private ActivityStreamdb db = null;
		private HttpServer server = null;
		
		public LogoutHandler(ActivityStreamdb db, HttpServer server) {
			this.db = db;
			this.server = server;
		}
		
	        public void handle(HttpExchange t) throws IOException {
		
			String response = "";
			
			HTMLBuilder html = new HTMLBuilder();
			html.appendHTMLHead();
			html.appendHTMLStyle();
			html.appendHTMLScript();
			html.appendHTMLHeadEnd();
			html.appendMainStart();
			html.append("<div style='text-align:center;'>GoodBye<div>");
			html.appendEndDiv();
			html.appendEndBody();
			
		        t.sendResponseHeaders(200, html.getHTML().length());
		        OutputStream os = t.getResponseBody();
			os.write(html.getHTML().getBytes());
			os.close();

			System.out.println("Database shutdown start");
			try {
				db.shutdown();
			} catch (Exception e) {
				e.printStackTrace();
			}
			System.out.println("Database shutdown complete");
			System.out.println("HttpServer shutdown start");
			server.stop(0);
			System.out.println("HttpServer shutdown complete");
		}
	}


	static class SettingsHandler implements HttpHandler
	{
		private ActivityStreamdb db = null;
		
		public SettingsHandler(ActivityStreamdb db) {
			this.db = db;
		}
		
	        public void handle(HttpExchange t) throws IOException {
		
			String response = "";
			String setting = "";

			processMessages processor = new processMessages(db);
			processor.process();
			
			HTMLBuilder html = new HTMLBuilder();
			html.appendDefaultStart();
			html.appendSettingsLeftMenu();
			html.appendEndDiv();
			html.appendMainStart();

			@SuppressWarnings("unchecked")
			Map<String, Object> params = (Map<String, Object>)t.getAttribute("parameters");

			if (params.containsKey("setting"))
			{
				setting = (String)params.get("setting");
			}

			if (t.getRequestMethod().equalsIgnoreCase("POST"))
			{

				InputStream is = t.getRequestBody();

				stream2File fstream = new stream2File();
				File tmpfile = fstream.getstream2file(is);

				try {
					DataSource ds = new FileDataSource(tmpfile);
					FormdataMultipart forminput = new FormdataMultipart(ds);
					Hashtable paramsa = forminput.getParameters();
					if (paramsa.containsKey("add_hashtag"))
					{
						String[] hasharr = (String[])paramsa.get("hashtag_name");
						String hashtag = hasharr[0];
						String INSERT_RECORD = "INSERT INTO bm_settings(setting,value) VALUES(?,?)";
						PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
						pstmt.setString(1, "hashtag");
						pstmt.setString(2, hashtag);
						int i = pstmt.executeUpdate();
						if (i == -1) {
							System.out.println("db error : " );
						}
						pstmt.close();
					}
					if (paramsa.containsKey("del_hashtag"))
					{
						String[] hasharr = (String[])paramsa.get("hashtag_name");
						String hashtag = hasharr[0];
						String INSERT_RECORD = "DELETE FROM bm_settings WHERE value=?";
						PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
						pstmt.setString(1, hashtag);
						int i = pstmt.executeUpdate();
						if (i == -1) {
							System.out.println("db error : " );
						}
						pstmt.close();
					}
					if (paramsa.containsKey("upd_bmapi"))
					{
						String[] bmapi_iparr = (String[])paramsa.get("bmapi_ip");
						String bmapi_ip = bmapi_iparr[0];
						String INSERT_RECORD = "UPDATE bm_settings SET value=? WHERE setting=?";
						PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
						pstmt.setString(1, bmapi_ip);
						pstmt.setString(2, "bmapi_ip");
						int i = pstmt.executeUpdate();
						if (i == -1) {
							System.out.println("db error : " );
						}
						pstmt.close();
						String[] bmapi_portarr = (String[])paramsa.get("bmapi_port");
						String bmapi_port = bmapi_portarr[0];
						INSERT_RECORD = "UPDATE bm_settings SET value=? WHERE setting=?";
						pstmt = db.conn.prepareStatement(INSERT_RECORD);
						pstmt.setString(1, bmapi_port);
						pstmt.setString(2, "bmapi_port");
						i = pstmt.executeUpdate();
						if (i == -1) {
							System.out.println("db error : " );
						}
						pstmt.close();
						String[] bmapi_userarr = (String[])paramsa.get("bmapi_user");
						String bmapi_user = bmapi_userarr[0];
						INSERT_RECORD = "UPDATE bm_settings SET value=? WHERE setting=?";
						pstmt = db.conn.prepareStatement(INSERT_RECORD);
						pstmt.setString(1, bmapi_user);
						pstmt.setString(2, "bmapi_user");
						i = pstmt.executeUpdate();
						if (i == -1) {
							System.out.println("db error : " );
						}
						pstmt.close();
						String[] bmapi_passwordarr = (String[])paramsa.get("bmapi_password");
						String bmapi_password = bmapi_passwordarr[0];
						INSERT_RECORD = "UPDATE bm_settings SET value=? WHERE setting=?";
						pstmt = db.conn.prepareStatement(INSERT_RECORD);
						pstmt.setString(1, bmapi_password);
						pstmt.setString(2, "bmapi_password");
						i = pstmt.executeUpdate();
						if (i == -1) {
							System.out.println("db error : " );
						}
						pstmt.close();
						String[] bmapi_clientarr = (String[])paramsa.get("bmapi_client");
						String bmapi_client = bmapi_clientarr[0];
						INSERT_RECORD = "UPDATE bm_settings SET value=? WHERE setting=?";
						pstmt = db.conn.prepareStatement(INSERT_RECORD);
						pstmt.setString(1, bmapi_client);
						pstmt.setString(2, "bmapi_client");
						i = pstmt.executeUpdate();
						if (i == -1) {
							System.out.println("db error : " );
						}
						pstmt.close();
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}

			if (setting.equals("hashtags"))
			{
				response = response + "<form name='add_hashtag' action='/settings?setting=" + setting + "' method='post' enctype='multipart/form-data'>";
				response = response + "Hashtag:<br><input name=hashtag_name><br>";
				response = response + "<input type=submit name='add_hashtag' value='Add Hashtag'>";
				response = response + "</form>";
				response = response + "<br>";
				response = response + "<form name='del_hashtag' action='/settings?setting=" + setting + "' method='post' enctype='multipart/form-data'>";
				response = response + "Hashtag Name:<br><select name=hashtag_name>";
				try {
					String query = "SELECT value FROM bm_settings WHERE setting='hashtag'";
					ResultSet dbq = db.query(query);
					Object o = null;
					for (; dbq.next(); ) {
						o = dbq.getObject(1);
						String hashtag = (String)o;
						response = response + "<option value='" + hashtag + "'>" + hashtag + "</option>";
					}
				} catch (SQLException ex3) {
					ex3.printStackTrace();
				}
				response = response + "</select>";
				response = response + "<br><input type=submit name='del_hashtag' value='Delete Hashtag'>";
				response = response + "</form>";
				
			}

			if (setting.equals("bm_api"))
			{
				response = response + "<form name='upd_bmapi' action='/settings?setting=" + setting + "' method='post' enctype='multipart/form-data'>";
				try {
					String query = "SELECT value FROM bm_settings WHERE setting='bmapi_ip'";
					ResultSet dbq = db.query(query);
					Object o = null;
					for (; dbq.next(); ) {
						o = dbq.getObject(1);
						String bmapi_ip = (String)o;
						response = response + "BM API Host:<br><input name=bmapi_ip value='" + bmapi_ip + "'><br>";
					}
				} catch (SQLException ex3) {
					ex3.printStackTrace();
				}
				try {
					String query = "SELECT value FROM bm_settings WHERE setting='bmapi_port'";
					ResultSet dbq = db.query(query);
					Object o = null;
					for (; dbq.next(); ) {
						o = dbq.getObject(1);
						String bmapi_port = (String)o;
						response = response + "BM API Port Number:<br><input name=bmapi_port value='" + bmapi_port + "'><br>";
					}
				} catch (SQLException ex3) {
					ex3.printStackTrace();
				}
				try {
					String query = "SELECT value FROM bm_settings WHERE setting='bmapi_user'";
					ResultSet dbq = db.query(query);
					Object o = null;
					for (; dbq.next(); ) {
						o = dbq.getObject(1);
						String bmapi_user = (String)o;
						response = response + "BM API User:<br><input name=bmapi_user value='" + bmapi_user + "'><br>";
					}
				} catch (SQLException ex3) {
					ex3.printStackTrace();
				}
				try {
					String query = "SELECT value FROM bm_settings WHERE setting='bmapi_password'";
					ResultSet dbq = db.query(query);
					Object o = null;
					for (; dbq.next(); ) {
						o = dbq.getObject(1);
						String bmapi_password = (String)o;
						response = response + "BM API Password:<br><input type=password name=bmapi_password value='" + bmapi_password + "'><br>";
					}
				} catch (SQLException ex3) {
					ex3.printStackTrace();
				}
				try {
					String query = "SELECT value FROM bm_settings WHERE setting='bmapi_client'";
					ResultSet dbq = db.query(query);
					Object o = null;
					for (; dbq.next(); ) {
						o = dbq.getObject(1);
						String bmapi_client = (String)o;
						if (bmapi_client.equals("false"))
						{
							response = response + "Use browser interface as mail client<input type='radio' name='bmapi_client' value='false' checked />No<input type='radio' name='bmapi_client' value='true' />Yes<br>";
						} else {
							response = response + "Use browser interface as mail client<input type='radio' name='bmapi_client' value='false' />No<input type='radio' name='bmapi_client' value='true' checked />Yes<br>";
						}
					}
				} catch (SQLException ex3) {
					ex3.printStackTrace();
				}
				response = response + "<input type=submit name='upd_bmapi' value='Update'>";
				response = response + "</form>";				
			}

			html.append(response);
			html.appendEndDiv();
			html.appendEndBody();
		        t.sendResponseHeaders(200, html.getHTML().length());
		        OutputStream os = t.getResponseBody();
			os.write(html.getHTML().getBytes());
			os.close();

		}
	}

	static class MessagesHandler implements HttpHandler
	{
		private ActivityStreamdb db = null;
		
		public MessagesHandler(ActivityStreamdb db) {
			this.db = db;
		}
		
	        public void handle(HttpExchange t) throws IOException {

			String response = "";
			
			processMessages processor = new processMessages(db);
			processor.process();

			try {
				String INSERT_RECORD = "UPDATE bm_lastclick SET dtstamp=? WHERE wpage=?";
				PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
				java.sql.Timestamp  sqlDate = new java.sql.Timestamp(new java.util.Date().getTime());
				pstmt.setTimestamp(1, sqlDate);
				pstmt.setString(2, "MESSAGES");
				int i = pstmt.executeUpdate();
				if (i == -1) {
					System.out.println("db error : " );
				}
				pstmt.close();
			} catch (SQLException ex3) {
				ex3.printStackTrace();
			}

			if (t.getRequestMethod().equalsIgnoreCase("POST"))
			{

				InputStream is = t.getRequestBody();
				
				String mfolder = "";
				String mread = "";

				stream2File fstream = new stream2File();
				File tmpfile = fstream.getstream2file(is);

				try {
					DataSource ds = new FileDataSource(tmpfile);
					FormdataMultipart forminput = new FormdataMultipart(ds);
					Hashtable params = forminput.getParameters();
					if (params.containsKey("bmove_folder"))
					{
						String[] mfolderarr = (String[])params.get("move_folder");
						mfolder = mfolderarr[0];
						String[] mmsgid = (String[])params.get("chkmsg");
						for (int i=0; i<mmsgid.length; i++)
						{
							try {
								String INSERT_RECORD = "UPDATE bm_mail SET folder=? WHERE msgid=?";
								PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
								pstmt.setString(1, mfolder);
								pstmt.setString(2, mmsgid[i]);
								int d = pstmt.executeUpdate();
								if (d == -1) {
									System.out.println("db error : " );
								}
								pstmt.close();
							} catch (SQLException ex3) {
								ex3.printStackTrace();
							}
						}
					}
					if (params.containsKey("empty_trash"))
					{
						try {
							String INSERT_RECORD = "DELETE FROM bm_mail WHERE folder=?";
							PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
							pstmt.setString(1, "Trash");
							int d = pstmt.executeUpdate();
							if (d == -1) {
								System.out.println("db error : " );
							}
							pstmt.close();
						} catch (SQLException ex3) {
							ex3.printStackTrace();
						}
					}
					if (params.containsKey("bmark_read"))
					{
						String[] mreadarr = (String[])params.get("set_read");
						mread = mreadarr[0];
						String[] mmsgid = (String[])params.get("chkmsg");
						for (int i=0; i<mmsgid.length; i++)
						{
							try {
								String INSERT_RECORD = "UPDATE bm_mail SET read=? WHERE msgid=?";
								PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
								pstmt.setBoolean(1, Boolean.parseBoolean(mread));
								pstmt.setString(2, mmsgid[i]);
								int d = pstmt.executeUpdate();
								if (d == -1) {
									System.out.println("db error : " );
								}
								pstmt.close();
							} catch (SQLException ex3) {
								ex3.printStackTrace();
							}
						}
					}
					if (params.containsKey("bfolder"))
					{
						String[] mfolderarr = (String[])params.get("folder");
						mfolder = mfolderarr[0];
						try {
							String INSERT_RECORD = "INSERT INTO bm_mail_folders(folder) VALUES(?)";
							PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
							pstmt.setString(1, mfolder);
							int i = pstmt.executeUpdate();
							if (i == -1) {
								System.out.println("db error : " );
							}
							pstmt.close();
						} catch (SQLException ex3) {
							ex3.printStackTrace();
						}
					}

				} catch (Exception e) {
					e.printStackTrace();
				}
			}

			HTMLBuilder html = new HTMLBuilder();
			html.appendDefaultStart();
			html.appendMailLeftMenu();
			html.appendEndDiv();
			html.appendMainStart();

			@SuppressWarnings("unchecked")
			Map<String, Object> params = (Map<String, Object>)t.getAttribute("parameters");

			String folder = "Inbox";

			if (params.containsKey("folder"))
			{
				folder = (String)params.get("folder");
			}


			int count = 0;
			String csql = "SELECT COUNT(*) AS rowcount FROM bm_mail WHERE folder=?";
			try {
				PreparedStatement pstmt = db.conn.prepareStatement(csql);
				pstmt.setString(1, folder);
				ResultSet rs = pstmt.executeQuery();
				rs.next();
				count = rs.getInt(1);
				pstmt.close();

			} catch (SQLException ex3) {
				ex3.printStackTrace();
			}

			int maxPages = (count/100);
			if (maxPages*100 < count)
			{
				maxPages = maxPages + 1;
			}
			int page = 1;
			if (params.containsKey("page"))
			{
				String spage = (String)params.get("page");
				page = Integer.parseInt(spage);
			}
			int offset = (page*100) - 100;


			if (!folder.equals("Sent"))
			{
				if (folder.equals(""))
				{
					folder = "Inbox";
				}
				response = response + "<form name='move' action='/messages' method='post' enctype='multipart/form-data'>";
				response = response + "<input type='submit' name='bmove_folder' value='Move selected to:'>";
				response = response + "<select name='move_folder'>";
				try {
					ResultSet dbq = db.query("SELECT folder FROM bm_mail_folders");
					Object o = null;
					for (; dbq.next(); ) {
						o = dbq.getObject(1);
						String mfolder = o.toString();
						response  = response + "<option value='" + mfolder + "'>" + mfolder + "</option>";
					}
					db.st.close();
				} catch (SQLException ex3) {
					ex3.printStackTrace();
				} 
				response = response + "</select>";
				response = response + "<input type='submit' name='bmark_read' value='Mark selected:'>";
				response = response + "<select name='set_read'>";
				response = response + "<option value='true'>Read</option>";
				response = response + "<option value='false'>Unread</option>";
				response = response + "</select>";
				response = response + "<input type='submit' name='empty_trash' value='Empty Trash'>";
				response = response + "<table width=\"100%\"><thead><th><input align='left' type='checkbox' onClick='toggle(this)' name='chkmsg'></th><th>Sender</th><th>Subject</th><th>Received at</th></thead><tbody>";
				int i = 0;
			        try {
					String query = "SELECT msgid, read, subject, fromaddress, dtstamp FROM bm_mail WHERE folder='" + folder + "' ORDER BY dtstamp DESC LIMIT 100 OFFSET " + Integer.toString(offset) + "";
					ResultSet dbq = db.query(query);
					Object o = null;
					for (; dbq.next(); ) {
						response = response + "<tr>";
						String meh = "";
						o = dbq.getObject(1);
						String ref = o.toString();
						response = response + "<td><input type='checkbox' name='chkmsg' value='" + ref + "'></td>";						
						o = dbq.getObject(2);
						Boolean mread = (Boolean)o;
						o = dbq.getObject(4);
						meh = o.toString();
						response = response + "<td><a href='/message?msgid=" + ref + "'>";
						if (!mread)
						{
							response = response + "<b>";
						}
						response = response + meh;
						if (!mread)
						{
							response = response + "</b>";
						}
						response = response + "</a></td>";
						o = dbq.getObject(3);
						meh = o.toString();
						byte[] decoded = Base64.decodeBase64(meh);
						String meh2 = null;		
						try {
							meh2 = new String(decoded, "UTF-8");
						} catch (Exception e) {
							e.printStackTrace();
						}
						response = response + "<td><a href='/message?msgid=" + ref + "'>";
						if (!mread)
						{
							response = response + "<b>";
						}
						meh2 = meh2.replaceAll("<", "<");
						meh2 = meh2.replaceAll(">", ">");
						response = response + meh2;
						if (!mread)
						{
							response = response + "</b>";
						}
						response = response + "</a></td>";
						o = dbq.getObject(5);
						meh = o.toString();
						response = response + "<td width='150px'><a href='/message?msgid=" + ref + "'>";
						if (!mread)
						{
							response = response + "<b>";
						}
						response = response + meh;
						if (!mread)
						{
							response = response + "</b>";
						}
						response = response + "</a></td>";
						response = response + "</tr>";
						i++;
					}
					db.st.close();
				} catch (SQLException ex3) {
					ex3.printStackTrace();
				}
			} else {
				if (folder.equals(""))
				{
					folder = "Inbox";
				}
				response = response + "<form name='move' action='/messages' method='post' enctype='multipart/form-data'>";
				response = response + "<input type='submit' name='bmove_folder' value='Move selected to:'>";
				response = response + "<select name='move_folder'>";
				try {
					ResultSet dbq = db.query("SELECT folder FROM bm_mail_folders");
					Object o = null;
					for (; dbq.next(); ) {
						o = dbq.getObject(1);
						String mfolder = o.toString();
						response  = response + "<option value='" + mfolder + "'>" + mfolder + "</option>";
					}
					db.st.close();
				} catch (SQLException ex3) {
					ex3.printStackTrace();
				} 
				response = response + "</select>";
				response = response + "<input type='submit' name='bmark_read' value='Mark selected:'>";
				response = response + "<select name='set_read'>";
				response = response + "<option value='true'>Read</option>";
				response = response + "<option value='false'>Unread</option>";
				response = response + "</select>";
				response = response + "<input type='submit' name='empty_trash' value='Empty Trash'>";
				response = response + "<table width=\"100%\"><thead><th><input align='left' type='checkbox' onClick='toggle(this)' name='chkmsg'></th><th>Sender</th><th>Subject</th><th>Received at</th></thead><tbody>";
				int i = 0;
			        try {
					String query = "SELECT msgid, read, subject, fromaddress, dtstamp, ackdata FROM bm_mail WHERE folder='" + folder + "' ORDER BY dtstamp DESC LIMIT 100 OFFSET " + Integer.toString(offset) + "";
					ResultSet dbq = db.query(query);
					Object o = null;
					for (; dbq.next(); ) {
						response = response + "<tr>";
						String meh = "";
						o = dbq.getObject(1);
						String ref = o.toString();
						o = dbq.getObject(6);
						String ref2 = o.toString();
						if (!ref.equals("null"))
						{
							response = response + "<td><input type='checkbox' name='chkmsg' value='" + ref + "'></td>";						
						} else {
							response = response + "<td></td>";
						}						
						o = dbq.getObject(2);
						Boolean mread = (Boolean)o;
						o = dbq.getObject(4);
						meh = o.toString();
						response = response + "<td>";
						if (!ref.equals("null"))
						{
							response = response + "<a href='/message?msgid=" + ref + "'>";
						}
						if (!mread)
						{
							response = response + "<b>";
						}
						response = response + meh;
						if (!mread)
						{
							response = response + "</b>";
						}
						if (!ref.equals("null"))
						{
							response = response + "</a>";
						}
						response = response + "</td>";
						o = dbq.getObject(3);
						meh = o.toString();
						byte[] decoded = Base64.decodeBase64(meh);
						String meh2 = null;		
						try {
							meh2 = new String(decoded, "UTF-8");
						} catch (Exception e) {
							e.printStackTrace();
						}
						response = response + "<td>";
						if (!ref.equals("null"))
						{
							response = response + "<a href='/message?msgid=" + ref + "'>";
						}
						if (!mread)
						{
							response = response + "<b>";
						}
						meh2 = meh2.replaceAll("<", "<");
						meh2 = meh2.replaceAll(">", ">");
						response = response + meh2;
						if (!mread)
						{
							response = response + "</b>";
						}
						if (!ref.equals("null"))
						{
							response = response + "</a>";
						}
						response = response + "</td>";
						o = dbq.getObject(5);
						meh = o.toString();
						response = response + "<td width='150px'>";
						if (!ref.equals("null"))
						{
							response = response + "<a href='/message?msgid=" + ref + "'>";
						}
						if (!mread)
						{
							response = response + "<b>";
						}
						response = response + meh;
						if (!mread)
						{
							response = response + "</b>";
						}
						if (!ref.equals("null"))
						{
							response = response + "</a>";
						}
						response = response + "</td>";
						response = response + "</tr>";
						i++;
					}
					db.st.close();
				} catch (SQLException ex3) {
					ex3.printStackTrace();
				}
			} 


			response = response + "</tbody></table>";
			response = response + "</form>";
			response = response + "<p style=\"text-align:center\">";
			if (page > 1)
			{
				response = response + "<a href='/messages?folder=" + folder + "&page=1'>First</a> ";
				response = response + "<a href='/messages?folder=" + folder + "&page=" + (page - 1) + "'>Previous</a> ";
			}
			int opage = page;
			while ((opage <= page + 9) && (opage <= maxPages))
			{
				response = response + "<a href='/messages?folder=" + folder + "&page=" + opage + "'>" + opage + "</a> ";
				opage = opage + 1;
			}
			if (page < maxPages)
			{
				response = response + "<a href='/messages?folder=" + folder + "&page=" + (page + 1) + "'>Next</a> ";
			}
			response = response + "<a href='/messages?folder=" + folder + "&page=" + maxPages +"'>Last</a> ";
			response = response + "</p>";

			response = response + "</div>";
			response = response + "</body></html>";
			html.append(response);
			
		        t.sendResponseHeaders(200, html.getHTML().length());
		        OutputStream os = t.getResponseBody();
			os.write(html.getHTML().getBytes());
			os.close();

		}

	}

	static class MessageHandler implements HttpHandler
	{
		private ActivityStreamdb db = null;
		
		public MessageHandler(ActivityStreamdb db) {
			this.db = db;
		}
		
	        public void handle(HttpExchange t) throws IOException {

			String response = "";
			String msgid="";

			@SuppressWarnings("unchecked")
			Map<String, Object> params = (Map<String, Object>)t.getAttribute("parameters");

			msgid = (String)params.get("msgid");


			if (t.getRequestMethod().equalsIgnoreCase("POST"))
			{

				InputStream is = t.getRequestBody();
				
				String mfolder = "";

				stream2File fstream = new stream2File();
				File tmpfile = fstream.getstream2file(is);

				try {
					DataSource ds = new FileDataSource(tmpfile);
					FormdataMultipart forminput = new FormdataMultipart(ds);
					Hashtable paramsa = forminput.getParameters();
					if (paramsa.containsKey("bmove_folder"))
					{
						String[] mfolderarr = (String[])paramsa.get("move_folder");
						mfolder = mfolderarr[0];
						String INSERT_RECORD = "UPDATE bm_mail SET folder=? WHERE msgid=?";
						PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
						pstmt.setString(1, mfolder);
						pstmt.setString(2, msgid);
						int d = pstmt.executeUpdate();
						if (d == -1) {
							System.out.println("db error : " );
						}
						pstmt.close();
					}
					if (paramsa.containsKey("add_address"))
					{
						String[] addressarr = (String[])paramsa.get("address");
						String address = addressarr[0];
						String INSERT_RECORD = "INSERT INTO bm_profiles(address,following,follower,dtstamp) VALUES(?,?,?,?)";
						PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
						pstmt.setString(1, address);
						pstmt.setBoolean(2, false);
						pstmt.setBoolean(3, false); 
						java.sql.Timestamp  sqlDate = new java.sql.Timestamp(new java.util.Date().getTime());
						pstmt.setTimestamp(4, sqlDate);

						int d = pstmt.executeUpdate();
						if (d == -1) {
							System.out.println("db error : " );
						}
						pstmt.close();
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}

			try {
				String UPDATE_RECORD = "UPDATE bm_mail SET read=? WHERE msgid=?";
				PreparedStatement pstmtu = db.conn.prepareStatement(UPDATE_RECORD);
				pstmtu.setBoolean(1, true);
				pstmtu.setString(2, msgid);
				int du = pstmtu.executeUpdate();
				if (du == -1) {
					System.out.println("db error : " );
				}
				pstmtu.close();
			} catch (Exception e) {
				e.printStackTrace();
			}

			
			processMessages processor = new processMessages(db);
			processor.process();

			HTMLBuilder html = new HTMLBuilder();
			html.appendDefaultStart();
			html.appendMailLeftMenu();
			html.appendEndDiv();
			html.appendMainStart();

			response = response + "<table><tr><td>";
			response = response + "<form name='send' action='/send_message' method='post' enctype='multipart/form-data'>";
			response = response + "<input type='hidden' name='msgid' value='" + msgid + "'>";
			response = response + "<input type='submit' name='send' value='Reply'>";
			response = response + "<input type='submit' name='send' value='Forward'>";
			response = response + "</form><td>";

			response = response + "<td><form name='move' action='/message?msgid=" + msgid + "' method='post' enctype='multipart/form-data'>";
			response = response + "<input type='submit' name='bmove_folder' value='Move selected to:'>";
			response = response + "<select name='move_folder'>";
			try {
				ResultSet dbq = db.query("SELECT folder FROM bm_mail_folders");
				Object o = null;
				for (; dbq.next(); ) {
					o = dbq.getObject(1);
					String mfolder = o.toString();
					response  = response + "<option value='" + mfolder + "'>" + mfolder + "</option>";
				}
				db.st.close();
			} catch (SQLException ex3) {
				ex3.printStackTrace();
			} 
			response = response + "</select>";
			response = response + "</form></td>";
			response = response + "</tr></table>";



		        try {
				String qstring = "SELECT toaddress, fromaddress, subject, message FROM bm_mail WHERE msgid='" + msgid + "'";
				ResultSet dbq = db.query(qstring);
				Object o = null;
				for (; dbq.next(); ) {
					response = response + "<div>TO: ";
					o = dbq.getObject(1);
					String meh = o.toString();
					response = response + meh + "</div><br>";
					response = response + "<div>FROM: ";
					o = dbq.getObject(2);
					meh = o.toString();
					response = response + meh + "</div>";
					int count = 0;
					String csql = "SELECT COUNT(*) AS rowcount FROM bm_profiles WHERE address=?";
					try {
						PreparedStatement pstmt = db.conn.prepareStatement(csql);
						pstmt.setString(1, meh);
						ResultSet rs = pstmt.executeQuery();
						rs.next();
						count = rs.getInt(1);
						pstmt.close();
					} catch (SQLException ex3) {
						ex3.printStackTrace();
					}
					if (count == 0)
					{
						response = response + "<form name='profile' action='/message?msgid=" + msgid + "' method='post' enctype='multipart/form-data'>";
						response = response + "<input type='hidden' name='address' value='" + meh + "'>";
						response = response + "<input type='submit' name='add_address' value='Add to address book'>";
						response = response + "</form>";
					}
					response = response + "<br>";
					response = response + "<div>SUBJECT: ";
					o = dbq.getObject(3);
					meh = o.toString();
					byte[] decoded = Base64.decodeBase64(meh);
					String meh2 = null;		
					try {
						meh2 = new String(decoded, "UTF-8");
					} catch (Exception e) {
						e.printStackTrace();
					}
					response = response + meh2 + "</div><br>";
					response = response + "<div>MESSAGE: <pre>";
					o = dbq.getObject(4);
					meh = o.toString();
					decoded = Base64.decodeBase64(meh);
					meh2 = null;		
					try {
						meh2 = new String(decoded, "UTF-8");
					} catch (Exception e) {
						e.printStackTrace();
					}
					meh2 = meh2.replace("&", "&");
					meh2 = meh2.replace("\"", """);
					meh2 = meh2.replace("<", "<");
					meh2 = meh2.replace(">", ">");

					response = response + meh2 + "</pre></div><br>";

				}
				db.st.close();
			} catch (SQLException ex3) {
				ex3.printStackTrace();
			} 


			response = response + "</div></body></html>";
			html.append(response);
			
		        t.sendResponseHeaders(200, html.getHTML().length());
		        OutputStream os = t.getResponseBody();
			os.write(html.getHTML().getBytes());
			os.close();

		}

	}

	static class SendMessageHandler implements HttpHandler
	{
		
		private ActivityStreamdb db = null;

		public SendMessageHandler(ActivityStreamdb db) {
			this.db = db;
		}
		
	        public void handle(HttpExchange t) throws IOException {

			String To = "";
			String From = "";
			String Subject = "";
			String Message = "";

			@SuppressWarnings("unchecked")
			Map<String, Object> params = (Map<String, Object>)t.getAttribute("parameters");

			if (t.getRequestMethod().equalsIgnoreCase("GET"))
			{
				if (params.size() > 0)
				{
					To = (String)params.get("To");
					From = (String)params.get("From");
					Subject = (String)params.get("Subject");
					Message = (String)params.get("Message");
				}
			}

			if (t.getRequestMethod().equalsIgnoreCase("POST"))
			{

				InputStream is = t.getRequestBody();

				stream2File fstream = new stream2File();
				File tmpfile = fstream.getstream2file(is);

				try {
					DataSource ds = new FileDataSource(tmpfile);
					FormdataMultipart forminput = new FormdataMultipart(ds);
					Hashtable paramsa = forminput.getParameters();
					if (paramsa.containsKey("send"))
					{
					        try {
							String[] msgida = (String[])paramsa.get("msgid");
							String[] senda = (String[])paramsa.get("send");
							String qstring = "SELECT toaddress, fromaddress, subject, message FROM bm_mail WHERE msgid='" + msgida[0] + "'";
							ResultSet dbq = db.query(qstring);
							Object o = null;
							for (; dbq.next(); ) {
								if (senda[0].equals("Reply"))
								{				
									o = dbq.getObject(2);
									To = o.toString();
								}
								o = dbq.getObject(3);
								String meh = o.toString();
								byte[] decoded = Base64.decodeBase64(meh);
								Subject = null;		
								try {
									Subject = new String(decoded, "UTF-8");
								} catch (Exception e) {
									e.printStackTrace();
								}
								o = dbq.getObject(4);
								meh = o.toString();
								decoded = Base64.decodeBase64(meh);
								Message = null;		
								try {
									Message = new String(decoded, "UTF-8");
								} catch (Exception e) {
									e.printStackTrace();
								}
							}
							db.st.close();
						} catch (SQLException ex3) {
							ex3.printStackTrace();
						} 
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}


			processMessages processor = new processMessages(db);
			processor.process();

			String response = "";

			HTMLBuilder html = new HTMLBuilder();
			html.appendDefaultStart();
			html.appendMailLeftMenu();
			html.appendEndDiv();
			html.appendMainStart();

			response = response + "<form name='share' action='/send' method='post' enctype='multipart/form-data'><table>";
			if (!To.equals(""))
			{
				response = response + "<tr><td><td>To:</td><td><input name = 'To' style='width:538px' value='" + To + "'></td></tr>";
			} else {
				response = response + "<tr><td><td>To:</td><td><select name = 'To' style='width:538px' multiple size=5>";
				try {
					String query = "SELECT address, label FROM bm_profiles ORDER BY dtstamp DESC";
					ResultSet dbq = db.query(query);
					Object o = null;
					int count = 0;
					for (; dbq.next(); ) {
						o = dbq.getObject(1);
						String address = (String)o;
						o = dbq.getObject(2);
						String label = (String)o;
						if (label != null)
						{
							response = response + "<option value='" + address + "'>" + label + "</option>";
						} else {
							response = response + "<option value='" + address + "'>" + address + "</option>";
						}
					}
					db.st.close();
				} catch (SQLException ex3) {
					ex3.printStackTrace();
				} 
				response = response + "</select></td></tr>";
			}

			response = response + "<tr><td><td>From:</td><td><select name = 'From' style='width:538px'>";

			APIcall apicall = new APIcall();
			String xml = "<?xml version='1.0'?><methodCall><methodName>listAddresses</methodName></methodCall>";
	        	String response2 = apicall.getAPIcall(xml);
			
			try {
			
				DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
				DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
				Document doc = dBuilder.parse(new ByteArrayInputStream(response2.getBytes()));
				doc.getDocumentElement().normalize();
				
				NodeList nList = doc.getElementsByTagName("param");
				
				for (int temp = 0; temp < nList.getLength(); temp++)
				{
					Node nNode = nList.item(temp);
	 				if (nNode.getNodeType() == Node.ELEMENT_NODE)
					{
						Element eElement = (Element) nNode;
						response2 = eElement.getElementsByTagName("string").item(0).getTextContent();
					}
					
					JSONParser parser1 = new JSONParser();
					JSONParser parser2 = new JSONParser();
					JSONParser parser3 = new JSONParser();
					JSONParser parser4 = new JSONParser();
					KeyFinder finder1 = new KeyFinder();
					KeyFinder finder2 = new KeyFinder();
					KeyFinder finder3 = new KeyFinder();
					KeyFinder finder4 = new KeyFinder();
					finder1.setMatchKey("label");
					finder2.setMatchKey("address");
					finder3.setMatchKey("stream");
					finder4.setMatchKey("enabled");
					try {
						while(!finder1.isEnd())
						{
							parser1.parse(response2, finder1, true);
							parser2.parse(response2, finder2, true);
							parser3.parse(response2, finder3, true);
							parser4.parse(response2, finder4, true);
      							if(finder1.isFound())
							{
								finder1.setFound(false);
								String label = (String)finder1.getValue();
								String address = (String)finder2.getValue();
								long streaml = (long)finder3.getValue();
								int stream = (int)streaml;
								Boolean enabled = (Boolean)finder4.getValue();
								if (enabled)
								{
									response = response + "<option value='" + address + "'>";
									if (!label.equals(""))
									{
										response = response + label + "</option>";
									} else {
										response = response + address + "</option>";
									}
								}
							} else {
								finder1.endJSON();
							}
						}
					} catch(ParseException pe) {
						pe.printStackTrace();
					}
				}
   			} catch (Exception e) {
				e.printStackTrace();
			}

	
			response = response + "</select></td></tr>";
			response = response + "<tr><td><td>Subject:</td><td><input name = 'Subject' style='width:538px' value='" + Subject + "'></td></tr>";
			response = response + "<tr><td><td>Message:</td><td><textarea cols=50 name='Message' rows=6 style='height:170px;width:538px'>" + Message + "</textarea></td></tr>";
			response = response + "</table><input type='submit' value='Send'><input type = 'button' value = 'Choose image' onclick ='javascript:document.getElementById(\"imagefile\").click();'><input id = 'imagefile' type='file' style='visibility: hidden;' name='File' accept='image/*' onchange=\"loadImageFile();\"></form>";

			response = response + "<div id='imagePreview'></div>";
			html.append(response);
			html.appendEndDiv();
			html.appendEndBody();

		        t.sendResponseHeaders(200, html.getHTML().length());
		        OutputStream os = t.getResponseBody();
			os.write(html.getHTML().getBytes());
			os.close();

		}
	}

	static class SendHandler implements HttpHandler
	{
		
		private ActivityStreamdb db = null;

		public SendHandler(ActivityStreamdb db) {
			this.db = db;
		}
		
	        public void handle(HttpExchange t) throws IOException {

			String response = "";

			InputStream is = t.getRequestBody();

			if (t.getRequestMethod().equalsIgnoreCase("POST"))
			{
				
				String toaddress = "";
				String fromaddress = "";
				String subject = "";
				String message = "";

				stream2File fstream = new stream2File();
				File tmpfile = fstream.getstream2file(is);
				try {
					DataSource ds = new FileDataSource(tmpfile);
					FormdataMultipart forminput = new FormdataMultipart(ds);
					Hashtable params = forminput.getParameters();
					String[] toarr = (String[])params.get("To");
					for (int a=0; a<toarr.length; a++)
					{
						toaddress = toarr[a];
						String[] fromarr = (String[])params.get("From");
						fromaddress = fromarr[0];
						String[] subarr = (String[])params.get("Subject");
						base64processor encoded = new base64processor();
						subject = encoded.toString(subarr[0].getBytes());
						String[] messarr = (String[])params.get("Message");
						message = messarr[0];
					
						for (int i=0; i< forminput.getCount(); i++)
						{
							BodyPart bodprt = forminput.getBodyPart(i);
							DataHandler blah = bodprt.getDataHandler();
							InputStream is4 = blah.getInputStream();
							response = response + "\n";
							response = "<img src=\"data:" + blah.getContentType() + ";base64,";
							response = response + encoded.toString(IOUtils.toByteArray(is4));
							response = response + "\"";
							response = response + " alt=\"" + blah.getName() + "\" /";
							response = response + ">\n";
						}
						
						message = message + response;
						message = encoded.toString(message.getBytes());

						Send sender = new Send(toaddress, fromaddress, subject, message);
						String response2 = sender.sendMessage();
						
						System.out.println("Actkdata from send " + response2);						
	
						try {
							String INSERT_RECORD = "INSERT INTO bm_mail(ackdata,read,folder,toaddress,fromaddress,subject,message,encodingtype,dtstamp,msgid) VALUES(?,?,?,?,?,?,?,?,?,?)";
							PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
							pstmt.setString(1, response2);
							pstmt.setBoolean(2, true);
							pstmt.setString(3, "Sent");
							pstmt.setString(4, toaddress);
							pstmt.setString(5, fromaddress);
							pstmt.setString(6, subject);
							pstmt.setString(7, message);
							pstmt.setInt(8, 2);	
							java.sql.Timestamp  sqlDate = new java.sql.Timestamp(new java.util.Date().getTime());
							pstmt.setTimestamp(9, sqlDate);
							pstmt.setString(10, "null");
							int d = pstmt.executeUpdate();
							if (d == -1) {
								System.out.println("db error : " );
							}
							pstmt.close();
						} catch (SQLException ex3) {
							ex3.printStackTrace();
						}
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
					
			}

			processOutMessages processor = new processOutMessages(db);
			processor.process();


			response = "<!DOCTYPE HTML>";
			response = response + "<html lang=\"en-US\">";
			response = response + "    <head>";
			response = response + "        <meta charset=\"UTF-8\">";
			response = response + "        <meta http-equiv=\"refresh\" content=\"1;url=http://localhost:8000/messages\">";
			response = response + "        <script type=\"text/javascript\">";
			response = response + "            window.location.href = \"http://localhost:8000/messages\"";
			response = response + "        </script>";
			response = response + "        <title>Page Redirection</title>";
			response = response + "    </head>";
			response = response + "    <body>";
			response = response + "    </body>";
			response = response + "</html>";

		        t.sendResponseHeaders(200, response.length());
		        OutputStream os = t.getResponseBody();
			os.write(response.getBytes());
			os.close();



		}

	}

	static class ProfilesHandler implements HttpHandler
	{

		private ActivityStreamdb db = null;

		public ProfilesHandler(ActivityStreamdb db) {
			this.db = db;
		}

		public void handle(HttpExchange t) throws IOException {

			String response = "";
			String page = "follower";

			@SuppressWarnings("unchecked")
			Map<String, Object> params = (Map<String, Object>)t.getAttribute("parameters");

			if (params.containsKey("page"))
			{
				page = (String)params.get("page");
			}

			if (t.getRequestMethod().equalsIgnoreCase("POST"))
			{

				InputStream is = t.getRequestBody();

				stream2File fstream = new stream2File();
				File tmpfile = fstream.getstream2file(is);

				try {
					DataSource ds = new FileDataSource(tmpfile);
					FormdataMultipart forminput = new FormdataMultipart(ds);
					Hashtable paramsa = forminput.getParameters();
					if (paramsa.containsKey("add_address"))
					{
						String[] addressarr = (String[])paramsa.get("address");
						String address = addressarr[0];
						String[] followerarr = (String[])paramsa.get("follower");
						String follower = followerarr[0];
						String[] followingarr = (String[])paramsa.get("following");
						String following = followingarr[0];
						int count = 0;
						String csql = "SELECT COUNT(*) AS rowcount FROM bm_profiles WHERE address=?";
						try {
							PreparedStatement pstmt = db.conn.prepareStatement(csql);
							pstmt.setString(1, address);
							ResultSet rs = pstmt.executeQuery();
							rs.next();
							count = rs.getInt(1);
							pstmt.close();
						} catch (SQLException ex3) {
							ex3.printStackTrace();
						}
						if (count == 0)
						{
							String INSERT_RECORD = "INSERT INTO bm_profiles(address,follower,following) VALUES(?,?,?)";
							PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
							pstmt.setString(1, address);
							pstmt.setBoolean(2, Boolean.parseBoolean(follower));
							pstmt.setBoolean(3, Boolean.parseBoolean(following));
							int i = pstmt.executeUpdate();
							if (i == -1) {
								System.out.println("db error : " );
							}
							pstmt.close();
						}
						if (Boolean.parseBoolean(following))
						{
							Follow follow = new Follow(address);
							follow.follow();
						}
					}
					if (paramsa.containsKey("add_list"))
					{
						String[] listarr = (String[])paramsa.get("list_name");
						String list = listarr[0];
						String INSERT_RECORD = "INSERT INTO bm_profiles_lists(list,address) VALUES(?,?)";
						PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
						pstmt.setString(1, list);
						pstmt.setString(2, "dummy");
						int i = pstmt.executeUpdate();
						if (i == -1) {
							System.out.println("db error : " );
						}
						pstmt.close();
					}
					if (paramsa.containsKey("del_list"))
					{
						String[] listarr = (String[])paramsa.get("list_name");
						String list = listarr[0];
						String INSERT_RECORD = "DELETE FROM bm_profiles_lists WHERE list=?";
						PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
						pstmt.setString(1, list);
						int i = pstmt.executeUpdate();
						if (i == -1) {
							System.out.println("db error : " );
						}
						pstmt.close();
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}


			processMessages processor = new processMessages(db);
			processor.process();

			try {
				String INSERT_RECORD = "UPDATE bm_lastclick SET dtstamp=? WHERE wpage=?";
				PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
				java.sql.Timestamp  sqlDate = new java.sql.Timestamp(new java.util.Date().getTime());
				pstmt.setTimestamp(1, sqlDate);
				pstmt.setString(2, "FOLLOWERS");
				int i = pstmt.executeUpdate();
				if (i == -1) {
					System.out.println("db error : " );
				}
				pstmt.close();
			} catch (SQLException ex3) {
				ex3.printStackTrace();
			}

			HTMLBuilder html = new HTMLBuilder();
			html.appendDefaultStart();
			html.appendProfilesLeftMenu();
			html.appendEndDiv();
			html.appendMainStart();

			int offset = 0;
			if (page.equals("follower") || page.equals("following"))
			{
				if (page.equals("following"))
				{
					response = response + "<form name='add_profile' action='/followers?page=" + page + "' method='post' enctype='multipart/form-data'>";
					response = response + "Address:<br><input name=address><br>";
					response = response + "<input type=hidden name='follower' value='false'>";
					response = response + "<input type=hidden name='following' value='true'>";
					response = response + "<input type=submit name='add_address' value='Follow Address'>";
					response = response + "</form>";
				}
				try {
					String query = "SELECT address, label FROM bm_profiles WHERE " + page + "=true ORDER BY dtstamp DESC LIMIT 100 OFFSET " + Integer.toString(offset) + "";
					System.out.println("Retreive " + page + " details");
					ResultSet dbq = db.query(query);
					Object o = null;
					int count = 0;
					response = response + "<table>";
					for (; dbq.next(); ) {
						count++;
						if (count == 1)
						{
							response = response + "<tr>";
						}
						o = dbq.getObject(1);
						String address = (String)o;
						o = dbq.getObject(2);
						String label = (String)o;
						response = response + "<td>";
						response = response + label + "<br>";
						response = response + "<a href='/profile?address=" + address + "'>"+ address + "</a>";
						response = response + "</td>";
						if (count == 3)
						{
							response = response + "</tr>";
							count = 0;
						}
					}
					if ((count == 1) || (count == 2))
					{
						response = response + "</tr>";
					}
					response = response + "</table>";
					db.st.close();
				} catch (SQLException ex3) {
					ex3.printStackTrace();
				}
			}
			if (page.equals("mail_contacts"))
			{
				response = response + "<form name='add_profile' action='/followers?page=" + page + "' method='post' enctype='multipart/form-data'>";
				response = response + "Address:<br><input name=address><br>";
				response = response + "<input type=hidden name='follower' value='false'>";
				response = response + "<input type=hidden name='following' value='false'>";
				response = response + "<input type=submit name='add_address' value='Add Address'>";
				response = response + "</form>";

				try {
					String query = "SELECT address, label FROM bm_profiles WHERE follower=false AND following=false ORDER BY dtstamp DESC LIMIT 100 OFFSET " + Integer.toString(offset) + "";
					System.out.println("Retreive " + page + " details");
					ResultSet dbq = db.query(query);
					Object o = null;
					int count = 0;
					response = response + "<table>";
					for (; dbq.next(); ) {
						count++;
						if (count == 1)
						{
							response = response + "<tr>";
						}
						o = dbq.getObject(1);
						String address = (String)o;
						o = dbq.getObject(2);
						String label = (String)o;
						response = response + "<td>";
						response = response + label + "<br>";
						response = response + "<a href='/profile?address=" + address + "'>"+ address + "</a>";
						response = response + "</td>";
						if (count == 3)
						{
							response = response + "</tr>";
							count = 0;
						}
					}
					if ((count == 1) || (count == 2))
					{
						response = response + "</tr>";
					}
					response = response + "</table>";
					db.st.close();
				} catch (SQLException ex3) {
					ex3.printStackTrace();
				}
			}
			if (page.equals("lists"))
			{
				response = response + "<form name='add_list' action='/followers?page=" + page + "' method='post' enctype='multipart/form-data'>";
				response = response + "List Name:<br><input name=list_name><br>";
				response = response + "<input type=submit name='add_list' value='Add List'>";
				response = response + "</form>";
				response = response + "<br>";
				response = response + "<form name='del_list' action='/followers?page=" + page + "' method='post' enctype='multipart/form-data'>";
				response = response + "List Name:<br><select name=list_name>";
				try {
					String query = "SELECT DISTINCT list FROM bm_profiles_lists";
					System.out.println("Retreive list of follower lists");
					ResultSet dbq = db.query(query);
					Object o = null;
					for (; dbq.next(); ) {
						o = dbq.getObject(1);
						String list = (String)o;
						response = response + "<option value='" + list + "'>" + list + "</option>";
					}
				} catch (SQLException ex3) {
					ex3.printStackTrace();
				}
				response = response + "</select>";
				response = response + "<br><input type=submit name='del_list' value='Delete List'>";
				response = response + "</form>";

			}

			response = response + "</div></body></html>";
			html.append(response);
			
		        t.sendResponseHeaders(200, html.getHTML().length());
		        OutputStream os = t.getResponseBody();
			os.write(html.getHTML().getBytes());
			os.close();

		}

	}

	static class ProfileHandler implements HttpHandler
	{

		private ActivityStreamdb db = null;

		public ProfileHandler(ActivityStreamdb db) {
			this.db = db;
		}

		public void handle(HttpExchange t) throws IOException {

			String response = "";

			@SuppressWarnings("unchecked")
			Map<String, Object> params = (Map<String, Object>)t.getAttribute("parameters");

			String address = (String)params.get("address");

			if (t.getRequestMethod().equalsIgnoreCase("POST"))
			{

				InputStream is = t.getRequestBody();

				stream2File fstream = new stream2File();
				File tmpfile = fstream.getstream2file(is);

				try {
					DataSource ds = new FileDataSource(tmpfile);
					FormdataMultipart forminput = new FormdataMultipart(ds);
					Hashtable paramsa = forminput.getParameters();
					if (paramsa.containsKey("update"))
					{
						String[] labelarr = (String[])paramsa.get("label");
						String label = labelarr[0];
						String[] notesarr = (String[])paramsa.get("notes");
						String notes = notesarr[0];
						String INSERT_RECORD = "UPDATE bm_profiles SET label=?, notes=? WHERE address=?";
						PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
						pstmt.setString(1, label);
						pstmt.setString(2, notes);
						pstmt.setString(3, address);
						int d = pstmt.executeUpdate();
						if (d == -1) {
							System.out.println("db error : " );
						}
						pstmt.close();
					}
					if (paramsa.containsKey("follow"))
					{
						Follow follow = new Follow(address);
						follow.follow();
					}
					if (paramsa.containsKey("unfollow"))
					{
						Follow follow = new Follow(address);
						follow.unfollow();
					}
					if (paramsa.containsKey("delete"))
					{
						Follow follow = new Follow(address);
						follow.unfollow();
						String INSERT_RECORD = "DELETE FROM bm_profiles WHERE address=?";
						PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
						pstmt.setString(1, address);
						int d = pstmt.executeUpdate();
						if (d == -1) {
							System.out.println("db error : " );
						}
						pstmt.close();

					}
					if (paramsa.containsKey("add_to_list"))
					{
						String[] listarr = (String[])paramsa.get("list_name");
						String list = listarr[0];
						String INSERT_RECORD = "INSERT INTO bm_profiles_lists(list, address) VALUES(?,?)";
						PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
						pstmt.setString(1, list);
						pstmt.setString(2, address);
						int i = pstmt.executeUpdate();
						if (i == -1) {
							System.out.println("db error : " );
						}
						pstmt.close();
					}
					if (paramsa.containsKey("del_from_list"))
					{
						String[] listarr = (String[])paramsa.get("list_name");
						String list = listarr[0];
						String INSERT_RECORD = "DELETE FROM bm_profiles_lists WHERE list=? AND address=?";
						PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
						pstmt.setString(1, list);
						pstmt.setString(2, address);
						int i = pstmt.executeUpdate();
						if (i == -1) {
							System.out.println("db error : " );
						}
						pstmt.close();
					}

				} catch (Exception e) {
					e.printStackTrace();
				}
			}


			processMessages processor = new processMessages(db);
			processor.process();

			HTMLBuilder html = new HTMLBuilder();
			html.appendDefaultStart();
			html.appendProfilesLeftMenu();
			html.appendEndDiv();
			html.appendMainStart();

			String label = "";
			String notes = "";
			Boolean follower = false;
			Boolean following = false;

			try {
				String query = "SELECT label, notes, follower, following FROM bm_profiles WHERE address='" + address + "'";
				System.out.println("Retrieving address details");
				ResultSet dbq = db.query(query);
				Object o = null;
				int count = 0;
				response = response + "<table>";
				for (; dbq.next(); ) {
					count++;
					if (count == 1)
					{
						response = response + "<tr>";
					}
					o = dbq.getObject(1);
					label = (String)o;
					o = dbq.getObject(2);
					notes = (String)o;
					o = dbq.getObject(3);
					follower = (Boolean)o;
					o = dbq.getObject(4);
					following = (Boolean)o;
				}
				db.st.close();
			} catch (SQLException ex3) {
				ex3.printStackTrace();
			}

			response = response + "<div>" + address + "</div>";
			if (follower)
			{
				response = response + "<div>(Follower)</div>";
			}
			response = response + "<form name='update_profile' action='/profile?address=" + address + "' method='post' enctype='multipart/form-data'>";
			response = response + "Label:<br><input name=label value='" + label + "'><br>";
			response = response + "Notes:<br><textarea cols=50 name='notes' rows=6 style='height:170px;width:538px'>" + notes + "</textarea><br>";
			response = response + "<input type=submit name='update' value='Update Profile'>";
			response = response + "</form>";
			response = response + "<form name='following' action='/send_message' method='get'>";
			response = response + "<input type=hidden name='To' value='" + address + "'>";
			response = response + "<input type=hidden name='From' value=' '>";
			response = response + "<input type=hidden name='Subject' value=' '>";
			response = response + "<input type=hidden name='Message' value=' '>";
			response = response + "<input type=submit name='send' value='Send Message'>";
			response = response + "</form>";
			response = response + "</div></body></html>";
			if (follower)
			{
				ArrayList<String> addlist = new ArrayList<String>();
				ArrayList<String> dellist = new ArrayList<String>();
				try {
					String query = "SELECT list FROM bm_profiles_lists WHERE address='" + address + "'";
					System.out.println("Checking follower list "+ address + " belongs to");
					ResultSet dbq = db.query(query);
					Object o = null;
					for (; dbq.next(); ) {
						o = dbq.getObject(1);
						String list = (String)o;
						dellist.add(list);
					}
				} catch (SQLException ex3) {
					ex3.printStackTrace();
				}

				try {
					String query = "SELECT DISTINCT list FROM bm_profiles_lists";
					System.out.println("Checking available lists");
					ResultSet dbq = db.query(query);
					Object o = null;
					for (; dbq.next(); ) {
						o = dbq.getObject(1);
						String list = (String)o;
						if (!dellist.contains(list))
						{
							addlist.add(list);
						}
					}
				} catch (SQLException ex3) {
					ex3.printStackTrace();
				}

				response = response + "<form name='add_to_list' action='/profile?address=" + address + "' method='post' enctype='multipart/form-data'>";
				response = response + "<input type=submit name='add_to_list' value='Add to list:'>";
				response = response + "<select name=list_name>";
				for (int i=0; i<addlist.size(); i++)
				{
					response = response + "<option value='" + addlist.get(i) + "'>" + addlist.get(i) + "</option>";
				}
				response = response + "</select>";
				response = response + "</form>";

				response = response + "<form name='del_from_list' action='/profile?address=" + address + "' method='post' enctype='multipart/form-data'>";
				response = response + "<input type=submit name='del_from_list' value='Delete from list:'>";
				response = response + "<select name=list_name>";
				for (int i=0; i<dellist.size(); i++)
				{
					response = response + "<option value='" + dellist.get(i) + "'>" + dellist.get(i) + "</option>";
				}
				response = response + "</select>";
				response = response + "</form>";
				
				if (!following)
				{
					response = response + "<form name='following' action='/profile?address=" + address + "' method='post' enctype='multipart/form-data'>";
					response = response + "<input type=submit name='follow' value='Follow'>";
					response = response + "</form>";
				}

			} 
			if (following)
			{
				response = response + "<form name='following' action='/profile?address=" + address + "' method='post' enctype='multipart/form-data'>";
				response = response + "<input type=submit name='unfollow' value='Unfollow'>";
				response = response + "</form>";
			}
			if (!follower)
			{
				response = response + "<form name='following' action='/profile?address=" + address + "' method='post' enctype='multipart/form-data'>";
				response = response + "<input type=submit name='delete' value='Delete'>";
				response = response + "</form>";
			}
			response = response + "</div></body></html>";
			html.append(response);
			
		        t.sendResponseHeaders(200, html.getHTML().length());
		        OutputStream os = t.getResponseBody();
			os.write(html.getHTML().getBytes());
			os.close();

		}

	}

	static class Send {

		private String toAddress = "";
		private String fromAddress = "";
		private String Subject = "";
		private String Message = "";

		public Send(String toAddress, String fromAddress, String Subject, String Message)
		{
			this.toAddress = toAddress;
			this.fromAddress = fromAddress;
			this.Subject = Subject;
			this.Message = Message;
		}

		public String sendMessage()
		{
			String xml = "<?xml version='1.0'?><methodCall><methodName>sendMessage</methodName><params><param><value><string>" + toAddress + "</string></value></param><param><value><string>" + fromAddress + "</string></value></param><param><value><string>" + Subject + "</string></value></param><param><value><string>" + Message + "</string></value></param></params></methodCall>";
			APIcall sendCall = new APIcall();
	        	String response2 = sendCall.getAPIcall(xml);
			try {
			
				DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
				DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
				Document doc = dBuilder.parse(new ByteArrayInputStream(response2.getBytes()));
				doc.getDocumentElement().normalize();	
				
				NodeList nList = doc.getElementsByTagName("param");
				
				for (int temp = 0; temp < nList.getLength(); temp++)
				{
					Node nNode = nList.item(temp);
					if (nNode.getNodeType() == Node.ELEMENT_NODE)
					{
						Element eElement = (Element) nNode;
						response2 = eElement.getElementsByTagName("string").item(0).getTextContent();
					}
				}
				
				
			} catch (Exception e) {
				e.printStackTrace();
			}
			return response2;
		}

	}

	static class Follow
	{

		String address = "";
		String user = "";

		public Follow(String address) {
			this.address = address;
			bmasAddresses useraddress = new bmasAddresses();
			this.user = useraddress.getUser();
		}

		public void follow()
		{
			
			try {
				String INSERT_RECORD = "UPDATE bm_profiles SET following=? WHERE address=?";
				PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
				pstmt.setBoolean(1, true);
				pstmt.setString(2, address);
				int d = pstmt.executeUpdate();
				if (d == -1) {
					System.out.println("db error : " );
				}
				pstmt.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
			base64processor encoded = new base64processor();
			String subjectp = "[BM-ActivityStream]";
			String subject = encoded.toString(subjectp.getBytes());
			String messagep = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>";
			String uuid = UUID.randomUUID().toString();
			messagep = messagep + "<activity><to><objectType>person</objectType><id>" + address + "</id></to><actor><objectType>person</objectType><id>" + user + "</id></actor><target><objectType>followers</objectType><id>" + uuid + "</id></target><verb>follow</verb><object><objectType>person</objectType><id>" + address + "</id></object></activity>";
			String message = encoded.toString(messagep.getBytes());
			Send sender = new Send(address, user, subject, message);
			sender.sendMessage();
			try {
				String INSERT_RECORD = "INSERT INTO bm_table(msgid,address,application,message,dtstamp) VALUES(?,?,?,?,?)";
				PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
				pstmt.setString(1, uuid);
				pstmt.setString(2, user);
				pstmt.setString(3, "followers");
				pstmt.setString(4, messagep);
				java.sql.Timestamp  sqlDate = new java.sql.Timestamp(new java.util.Date().getTime());
				System.out.println(sqlDate);
				pstmt.setTimestamp(5, sqlDate);
				int i = pstmt.executeUpdate();
				if (i == -1) {
					System.out.println("db error : " );
				}
				pstmt.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}

		}

		public void unfollow()
		{
			base64processor encoded = new base64processor();
			String subjectp = "[BM-ActivityStream]";
			String subject = encoded.toString(subjectp.getBytes());
			String messagep = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>";
			String uuid = UUID.randomUUID().toString();
			messagep = messagep + "<activity><to><objectType>person</objectType><id>" + address + "</id></to><actor><objectType>person</objectType><id>" + user + "</id></actor><target><objectType>followers</objectType><id>" + uuid + "</id></target><verb>unfollow</verb><object><objectType>person</objectType><id>" + address + "</id></object></activity>";
			String message = encoded.toString(messagep.getBytes());
			Send sender = new Send(address, user, subject, message);
			sender.sendMessage();

			try {
				String INSERT_RECORD = "UPDATE bm_profiles SET following=? WHERE address=?";
				PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
				pstmt.setBoolean(1, false);
				pstmt.setString(2, address);
				int d = pstmt.executeUpdate();
				if (d == -1) {
					System.out.println("db error : " );
				}
				pstmt.close();
			} catch (Exception e) {
				e.printStackTrace();
			}

			try {
				String INSERT_RECORD = "INSERT INTO bm_table(msgid,address,application,message,dtstamp) VALUES(?,?,?,?,?)";
				PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
				pstmt.setString(1, uuid);
				pstmt.setString(2, user);
				pstmt.setString(3, "followers");
				pstmt.setString(4, messagep);
				java.sql.Timestamp  sqlDate = new java.sql.Timestamp(new java.util.Date().getTime());
				System.out.println(sqlDate);
				pstmt.setTimestamp(5, sqlDate);
				int i = pstmt.executeUpdate();
				if (i == -1) {
					System.out.println("db error : " );
				}
				pstmt.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}

	}

	static class Follower
	{

		String address = "";
	
		public Follower(String address) {
			this.address = address;
		}

		public void followed()
		{
			try {
				System.out.println("Setting follower to true for " + address);
				String INSERT_RECORD = "UPDATE bm_profiles SET follower=? WHERE address=?";
				PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
				pstmt.setBoolean(1, true);
				pstmt.setString(2, address);
				int d = pstmt.executeUpdate();
				if (d == -1) {
					System.out.println("db error : " );
				}
				pstmt.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		public void unfollowed()
		{
			try {
				System.out.println("Setting follower to false for " + address);
				String INSERT_RECORD = "UPDATE bm_profiles SET follower=? WHERE address=?";
				PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
				pstmt.setBoolean(1, false);
				pstmt.setString(2, address);
				int d = pstmt.executeUpdate();
				if (d == -1) {
					System.out.println("db error : " );
				}
				pstmt.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

	}


	static class Like
	{

		Node activity = null;
		String address = "";
		String targetid = "";
		String replyid = "";
		String user = "";

		public Like(Node activity, String address, String targetid, String replyid) {
			this.activity = activity;
			this.address = address;
			this.targetid = targetid;
			this.replyid = replyid;
			bmasAddresses useraddress = new bmasAddresses();
			this.user = useraddress.getUser();
		}

		public void like()
		{
			String messagep = "";
			ArrayList<String> recipients = new ArrayList<String>();
			if ((!recipients.contains(address)) && (!address.equals(user)))
			{
				recipients.add(address);
			}
			Element activityE = (Element) activity;
			NodeList toNL = activityE.getElementsByTagName("to");
			for (int z = 0; z<toNL.getLength(); z++)
			{
				Node toN = toNL.item(z);
				Element toE = (Element) toN;
				String addressee = toE.getElementsByTagName("id").item(0).getTextContent();
				if ((!recipients.contains(addressee)) && (!addressee.equals(user)))
				{
					recipients.add(addressee);
				}
			}
			base64processor encoded = new base64processor();
			String subjectp = "[BM-ActivityStream]";
			String subject = encoded.toString(subjectp.getBytes());
			messagep = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>";
			messagep = messagep + "<activity>";
			for (int y =0; y<recipients.size(); y++)
			{
				messagep = messagep + "<to><objectType>person</objectType><id>" + recipients.get(y) + "</id></to>";
			}
			messagep = messagep + "<actor><objectType>person</objectType><id>" + user + "</id></actor><target><objectType>news</objectType><id>" + targetid + "</id></target><verb>like</verb><object><inReplyTo>" + replyid + "</inReplyTo><id>" + replyid + "." + UUID.randomUUID().toString() + "</id></object></activity>";
			String message = encoded.toString(messagep.getBytes());
			for (int y =0; y<recipients.size(); y++)
			{
				Send sender = new Send(recipients.get(y), user, subject, message);
				sender.sendMessage();
			}
			try {
				DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
				DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
				Document doc = dBuilder.parse(new ByteArrayInputStream(messagep.getBytes()));
				doc.getDocumentElement().normalize();
				Node activityNode = doc.getElementsByTagName("activity").item(0);
				long receivedTime = new java.util.Date().getTime();
				NewsProcessor newsprocess = new NewsProcessor(user, receivedTime/1000L, activityNode, messagep);
				newsprocess.process();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

	}


	static class Comment
	{

		Node activity = null;
		String address = "";
		String targetid = "";
		String replyid = "";
		String user = "";
		String comment = "";
		String comment_type = "";

		public Comment(Node activity, String address, String targetid, String replyid, String comment, String comment_type) {
			this.activity = activity;
			this.address = address;
			this.targetid = targetid;
			this.replyid = replyid;
			bmasAddresses useraddress = new bmasAddresses();
			this.user = useraddress.getUser();
			this.comment = comment;
			this.comment_type = comment_type;
		}

		public void comment()
		{
			String messagep = "";
			ArrayList<String> recipients = new ArrayList<String>();
			if ((!recipients.contains(address)) && (!address.equals(user)))
			{
				recipients.add(address);
			}
			Element activityE = (Element) activity;
			NodeList toNL = activityE.getElementsByTagName("to");
			for (int z = 0; z<toNL.getLength(); z++)
			{
				Node toN = toNL.item(z);
				Element toE = (Element) toN;
				String addressee = toE.getElementsByTagName("id").item(0).getTextContent();
				if ((!recipients.contains(addressee)) && (!addressee.equals(user)))
				{
					recipients.add(addressee);
				}
			}
			base64processor encoded = new base64processor();
			String subjectp = "[BM-ActivityStream]";
			String subject = encoded.toString(subjectp.getBytes());
			messagep = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>";
			messagep = messagep + "<activity>";
			for (int y =0; y<recipients.size(); y++)
			{
				messagep = messagep + "<to><objectType>person</objectType><id>" + recipients.get(y) + "</id></to>";
			}
			messagep = messagep + "<actor><objectType>person</objectType><id>" + user + "</id></actor><target><objectType>news</objectType><id>" + targetid + "</id></target><verb>comment</verb><object><inReplyTo>" + replyid + "</inReplyTo><id>" + replyid + "." + UUID.randomUUID().toString() + "</id><content>" + comment + "</content></object></activity>";
			String message = encoded.toString(messagep.getBytes());
			if (comment_type.equals("Anonymous"))
			{
				bmasAddresses chanaddress = new bmasAddresses();
				this.user = chanaddress.getChan();
			}
			for (int y =0; y<recipients.size(); y++)
			{
				Send sender = new Send(recipients.get(y), user, subject, message);
				sender.sendMessage();
			}
			try {
				DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
				DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
				Document doc = dBuilder.parse(new ByteArrayInputStream(messagep.getBytes()));
				doc.getDocumentElement().normalize();
				Node activityNode = doc.getElementsByTagName("activity").item(0);
				long receivedTime = new java.util.Date().getTime();
				NewsProcessor newsprocess = new NewsProcessor(user, receivedTime/1000L, activityNode, messagep);
				newsprocess.process();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

	}

	static class Post
	{
		String addresstype = "";
		String[] addressees = null;
		String content = "";
		ArrayList<String> images = new ArrayList<String>();
		String user = "";
		String comment = "";

		public Post(String addresstype, String[] addressees, String content, ArrayList<String> images) {
			this.addresstype = addresstype;
			this.addressees = addressees;
			this.content = content;
			this.images = images;
			bmasAddresses useraddress = new bmasAddresses();
			this.user = useraddress.getUser();
		}

		public void post()
		{
			String messagep = "";
			ArrayList<String> recipients = new ArrayList<String>();
			if (addresstype.equals("Followers"))
			{
				for (int z = 0; z<addressees.length; z++)
				{
					recipients.add(addressees[z]);
				}
			}
			if (addresstype.equals("Lists"))
			{
				for (int z = 0; z<addressees.length; z++)
				{
					try {
						String query = "SELECT address FROM bm_profiles_lists WHERE list='" + addressees[z] + "'";
						ResultSet dbq = db.query(query);
						Object o = null;
						for (; dbq.next(); ) {
							o = dbq.getObject(1);
							String address = (String)o;
							recipients.add(address);
						}
					} catch (SQLException ex3) {
						ex3.printStackTrace();
					}
				}
			}
			if (addresstype.equals("Public"))
			{
				bmasAddresses getaddress = new bmasAddresses();
				recipients.add(getaddress.getChan());
				if (addressees[0].equals("Anonymous"))
				{
					this.user = getaddress.getChan();
				}	
			}
			if (recipients.size() > 0)
			{
				base64processor encoded = new base64processor();
				String subjectp = "[BM-ActivityStream]";
				String subject = encoded.toString(subjectp.getBytes());
				messagep = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>";
				messagep = messagep + "<activity>";
				for (int y =0; y<recipients.size(); y++)
				{
					messagep = messagep + "<to><objectType>person</objectType><id>" + recipients.get(y) + "</id></to>";
				}
				messagep = messagep + "<actor><objectType>person</objectType><id>" + user + "</id></actor><target><objectType>news</objectType><id>" + UUID.randomUUID().toString() + "</id></target><verb>post</verb><object><content>" + content + "</content>";
				if (images.size() > 0)
				{
					messagep = messagep + "<image>" + images.get(0) + "</image>";
				}
				messagep = messagep + "</object></activity>";
				String message = encoded.toString(messagep.getBytes());
				for (int y =0; y<recipients.size(); y++)
				{
					Send sender = new Send(recipients.get(y), user, subject, message);
					sender.sendMessage();
				}
				try {
					DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
					DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
					Document doc = dBuilder.parse(new ByteArrayInputStream(messagep.getBytes()));
					doc.getDocumentElement().normalize();
					Node activityNode = doc.getElementsByTagName("activity").item(0);
					long receivedTime = new java.util.Date().getTime();
					NewsProcessor newsprocess = new NewsProcessor(user, receivedTime, activityNode, messagep);
					newsprocess.process();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}

	}


	static class bmasAddresses {

		public bmasAddresses()
		{
		}

		public String getUser()
		{

			String user = "";
			
			APIcall apicall = new APIcall();
			String xml = "<?xml version='1.0'?><methodCall><methodName>listAddresses</methodName></methodCall>";
	        	String response2 = apicall.getAPIcall(xml);
			
			try {
			
				DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
				DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
				Document doc = dBuilder.parse(new ByteArrayInputStream(response2.getBytes()));
				doc.getDocumentElement().normalize();
				
				NodeList nList = doc.getElementsByTagName("param");
				
				for (int temp = 0; temp < nList.getLength(); temp++)
				{
					Node nNode = nList.item(temp);
	 				if (nNode.getNodeType() == Node.ELEMENT_NODE)
					{
						Element eElement = (Element) nNode;
						response2 = eElement.getElementsByTagName("string").item(0).getTextContent();
					}
					
					JSONParser parser1 = new JSONParser();
					JSONParser parser2 = new JSONParser();
					JSONParser parser3 = new JSONParser();
					JSONParser parser4 = new JSONParser();
					KeyFinder finder1 = new KeyFinder();
					KeyFinder finder2 = new KeyFinder();
					KeyFinder finder3 = new KeyFinder();
					KeyFinder finder4 = new KeyFinder();
					finder1.setMatchKey("label");
					finder2.setMatchKey("address");
					finder3.setMatchKey("stream");
					finder4.setMatchKey("enabled");
					try {
						while(!finder1.isEnd())
						{
							parser1.parse(response2, finder1, true);
							parser2.parse(response2, finder2, true);
							parser3.parse(response2, finder3, true);
							parser4.parse(response2, finder4, true);
      							if(finder1.isFound())
							{
								finder1.setFound(false);
								String label = (String)finder1.getValue();
								String address = (String)finder2.getValue();
								long streaml = (long)finder3.getValue();
								int stream = (int)streaml;
								Boolean enabled = (Boolean)finder4.getValue();
								if (enabled)
								{
									if (label.equals("BM-ActivityStream-User"))
									{
										user = address;
									}
								}
							} else {
								finder1.endJSON();
							}
						}
					} catch(ParseException pe) {
						pe.printStackTrace();
					}
				}
   			} catch (Exception e) {
				e.printStackTrace();
			}
			return user;
		}

		public String getChan()
		{

			String user = "";
			
			APIcall apicall = new APIcall();
			String xml = "<?xml version='1.0'?><methodCall><methodName>listAddresses</methodName></methodCall>";
	        	String response2 = apicall.getAPIcall(xml);
			
			try {
			
				DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
				DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
				Document doc = dBuilder.parse(new ByteArrayInputStream(response2.getBytes()));
				doc.getDocumentElement().normalize();	
				
				NodeList nList = doc.getElementsByTagName("param");
				
				for (int temp = 0; temp < nList.getLength(); temp++)
				{
					Node nNode = nList.item(temp);
	 				if (nNode.getNodeType() == Node.ELEMENT_NODE)
					{
						Element eElement = (Element) nNode;
						response2 = eElement.getElementsByTagName("string").item(0).getTextContent();
					}
					
					JSONParser parser1 = new JSONParser();
					JSONParser parser2 = new JSONParser();
					JSONParser parser3 = new JSONParser();
					JSONParser parser4 = new JSONParser();
					KeyFinder finder1 = new KeyFinder();
					KeyFinder finder2 = new KeyFinder();
					KeyFinder finder3 = new KeyFinder();
					KeyFinder finder4 = new KeyFinder();
					finder1.setMatchKey("label");
					finder2.setMatchKey("address");
					finder3.setMatchKey("stream");
					finder4.setMatchKey("enabled");
					try {
						while(!finder1.isEnd())
						{
							parser1.parse(response2, finder1, true);
							parser2.parse(response2, finder2, true);
							parser3.parse(response2, finder3, true);
							parser4.parse(response2, finder4, true);
      							if(finder1.isFound())
							{
								finder1.setFound(false);
								String label = (String)finder1.getValue();
								String address = (String)finder2.getValue();
								long streaml = (long)finder3.getValue();
								int stream = (int)streaml;
								Boolean enabled = (Boolean)finder4.getValue();
								if (enabled)
								{
									if (label.equals("BM-ActivityStream-Chan-General"))
									{
										user = address;
									}
								}
							} else {
								finder1.endJSON();
							}
						}
					} catch(ParseException pe) {
						pe.printStackTrace();
					}
				}
   			} catch (Exception e) {
				e.printStackTrace();
			}
			return user;
		}


	}

	static class processMessages {

		private ActivityStreamdb db = null;

		public processMessages(ActivityStreamdb db)
		{
			this.db = db;
		}

		public void process()
		{
			processInMessages inProcessor = new processInMessages(db);
			inProcessor.process();
			processOutMessages outProcessor = new processOutMessages(db);
			outProcessor.process();
		}
		
	}

	static class processInMessages {
		
		private ActivityStreamdb db = null;
		
		public processInMessages(ActivityStreamdb db)
		{
			this.db = db;
		}
		
		public void process()
		{

			String bmapi_client = "";
			try {
				String query = "SELECT value FROM bm_settings WHERE setting='bmapi_client'";
				ResultSet dbq = db.query(query);
				Object o = null;
				for (; dbq.next(); ) {
					o = dbq.getObject(1);
					bmapi_client = (String)o;
				}
			} catch (SQLException ex3) {
				ex3.printStackTrace();
			}
			
			
			Boolean bm_as_processed = true;

			while (bm_as_processed)
			{
				bm_as_processed = false;
				
				APIcall apicall = new APIcall();
				String xml = "<?xml version='1.0'?><methodCall><methodName>getAllInboxMessages</methodName></methodCall>";
		        	String response = apicall.getAPIcall(xml);
				
				try {
					
					DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
					DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
					Document doc = dBuilder.parse(new ByteArrayInputStream(response.getBytes()));
					doc.getDocumentElement().normalize();	
					
					NodeList nList = doc.getElementsByTagName("param");
					
					for (int temp = 0; temp < nList.getLength(); temp++)
					{
						Node nNode = nList.item(temp);
		 				if (nNode.getNodeType() == Node.ELEMENT_NODE)
						{
							Element eElement = (Element) nNode;
							response = eElement.getElementsByTagName("string").item(0).getTextContent();
						}
							
						JSONParser parser1 = new JSONParser();
						JSONParser parser2 = new JSONParser();
						JSONParser parser3 = new JSONParser();
						JSONParser parser4 = new JSONParser();
						JSONParser parser5 = new JSONParser();
						JSONParser parser6 = new JSONParser();
						JSONParser parser7 = new JSONParser();
						KeyFinder finder1 = new KeyFinder();
						KeyFinder finder2 = new KeyFinder();
						KeyFinder finder3 = new KeyFinder();
						KeyFinder finder4 = new KeyFinder();
						KeyFinder finder5 = new KeyFinder();
						KeyFinder finder6 = new KeyFinder();
						KeyFinder finder7 = new KeyFinder();
						finder1.setMatchKey("msgid");
						finder2.setMatchKey("toAddress");
						finder3.setMatchKey("fromAddress");
						finder4.setMatchKey("subject");
						finder5.setMatchKey("message");	
						finder6.setMatchKey("encodingType");
						finder7.setMatchKey("receivedTime");
						try {
							while(!finder1.isEnd())
							{
								parser1.parse(response, finder1, true);
								parser2.parse(response, finder2, true);
								parser3.parse(response, finder3, true);
								parser4.parse(response, finder4, true);
								parser5.parse(response, finder5, true);
								parser6.parse(response, finder6, true);
								parser7.parse(response, finder7, true);
      								if(finder1.isFound())
								{
									finder1.setFound(false);
									String msgid = (String)finder1.getValue();
									String toAddress = (String)finder2.getValue();
									String fromAddress = (String)finder3.getValue();
									String ecSubject = (String)finder4.getValue();
									byte[] bdcSubject = Base64.decodeBase64(ecSubject);
									String subject = new String(bdcSubject, "UTF-8");
									String ecMessage = (String)finder5.getValue();
									long encodingTypel = (Long)finder6.getValue();
									int encodingType = (int)encodingTypel;
									long receivedTime = Long.valueOf((String)finder7.getValue()).longValue();
									if (!subject.startsWith("[BM-ActivityStream]"))
									{
										if (bmapi_client.equals("true"))
										{
											try {
							 					String INSERT_RECORD = "INSERT INTO bm_mail(msgid,read,folder,toaddress,fromaddress,subject,message,encodingtype,dtstamp) VALUES(?,?,?,?,?,?,?,?,?)";
												PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
												pstmt.setString(1, msgid);
												pstmt.setBoolean(2, false);
												pstmt.setString(3, "Inbox");
												pstmt.setString(4, toAddress);
												pstmt.setString(5, fromAddress);
												pstmt.setString(6, ecSubject);
												pstmt.setString(7, ecMessage);
												pstmt.setInt(8, encodingType);	
												java.sql.Timestamp  sqlDate = new java.sql.Timestamp(receivedTime*1000L);
												pstmt.setTimestamp(9, sqlDate);
												int d = pstmt.executeUpdate();
									       			if (d == -1) {
													System.out.println("db error : " );
												} else {	
													String xml2 = "<?xml version='1.0'?><methodCall><methodName>trashMessage</methodName><params><param><value><string>" + msgid + "</string></value></param></params></methodCall>";
										       	 		String response2 = apicall.getAPIcall(xml2);
												}
									       		 	pstmt.close();
											} catch (SQLException ex3) {
												ex3.printStackTrace();
											}
										}
									} else {
										System.out.println("Activity Stream Message");
										byte[] bdcMessage = Base64.decodeBase64(ecMessage);
										String message = new String(bdcMessage, "UTF-8");
										DocumentBuilderFactory dbFactory2 = DocumentBuilderFactory.newInstance();
										DocumentBuilder dBuilder2 = dbFactory2.newDocumentBuilder();
										Document doc2 = dBuilder2.parse(new ByteArrayInputStream(message.getBytes()));
										doc2.getDocumentElement().normalize();
										NodeList nList2 = doc2.getElementsByTagName("activity");
										String application = "";
										for (int temp2 = 0; temp2 < nList2.getLength(); temp2++)
										{
											Node nNode2 = nList2.item(temp2);
							 				if (nNode2.getNodeType() == Node.ELEMENT_NODE)
											{
												Element eElement = (Element) nNode2;
												Node targetNode = eElement.getElementsByTagName("target").item(0);
												Element targetElement = (Element) targetNode;
												application = targetElement.getElementsByTagName("objectType").item(0).getTextContent();
												if (application.equals("followers"))
												{
													bmasAddresses bmasaddresses = new bmasAddresses();
													String useraddress = bmasaddresses.getUser();
													String chanaddress = bmasaddresses.getChan();
													if (toAddress.equals(useraddress))
													{
														FollowersProcessor followprocess = new FollowersProcessor(fromAddress, receivedTime, nNode2, message);
														Boolean processed = followprocess.process();
														if (processed)
														{
															APIcall apicall2 = new APIcall();
															String xml2 = "<?xml version='1.0'?><methodCall><methodName>trashMessage</methodName><params><param><value><string>" + msgid + "</string></value></param></params></methodCall>";
													        	String apiout = apicall2.getAPIcall(xml2);
															bm_as_processed = true;
														}
													}
												}
												if (application.equals("news"))
												{
													bmasAddresses bmasaddresses = new bmasAddresses();
													String useraddress = bmasaddresses.getUser();
													String chanaddress = bmasaddresses.getChan();
													if ((toAddress.equals(useraddress)) || (toAddress.equals(chanaddress)))
													{
														NewsProcessor newsprocess = new NewsProcessor(fromAddress, receivedTime, nNode2, message);
														Boolean processed = newsprocess.process();
														if (processed)
														{
															APIcall apicall2 = new APIcall();
															String xml2 = "<?xml version='1.0'?><methodCall><methodName>trashMessage</methodName><params><param><value><string>" + msgid + "</string></value></param></params></methodCall>";
														       	String apiout = apicall2.getAPIcall(xml2);
															bm_as_processed = true;
														}
													}
												}
											}
										}
									}
								} else {
									finder1.endJSON();
								}
							}
						} catch(ParseException pe) {
							pe.printStackTrace();
						}
					}
   				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

	static class processOutMessages {
		
		private ActivityStreamdb db = null;
		
		public processOutMessages(ActivityStreamdb db)
		{
			this.db = db;
		}
		
		public void process()
		{

			APIcall apicall = new APIcall();
			String xml = "<?xml version='1.0'?><methodCall><methodName>getAllSentMessages</methodName></methodCall>";
	        	String response = apicall.getAPIcall(xml);
			
			try {
			
				DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
				DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
				Document doc = dBuilder.parse(new ByteArrayInputStream(response.getBytes()));
				doc.getDocumentElement().normalize();
				
				NodeList nList = doc.getElementsByTagName("param");
				
				for (int temp = 0; temp < nList.getLength(); temp++)
				{
					Node nNode = nList.item(temp);
	 				if (nNode.getNodeType() == Node.ELEMENT_NODE)
					{
						Element eElement = (Element) nNode;
						response = eElement.getElementsByTagName("string").item(0).getTextContent();
					}

				JSONParser parser1 = new JSONParser();
				JSONParser parser2 = new JSONParser();
				JSONParser parser3 = new JSONParser();
				JSONParser parser4 = new JSONParser();
				JSONParser parser5 = new JSONParser();
				JSONParser parser6 = new JSONParser();
				JSONParser parser7 = new JSONParser();
				JSONParser parser8 = new JSONParser();
				JSONParser parser9 = new JSONParser();
				KeyFinder finder1 = new KeyFinder();
				KeyFinder finder2 = new KeyFinder();
				KeyFinder finder3 = new KeyFinder();
				KeyFinder finder4 = new KeyFinder();
				KeyFinder finder5 = new KeyFinder();
				KeyFinder finder6 = new KeyFinder();
				KeyFinder finder7 = new KeyFinder();
				KeyFinder finder8 = new KeyFinder();
				KeyFinder finder9 = new KeyFinder();
				finder1.setMatchKey("msgid");
				finder2.setMatchKey("toAddress");
				finder3.setMatchKey("fromAddress");
				finder4.setMatchKey("subject");
				finder5.setMatchKey("message");	
				finder6.setMatchKey("encodingType");
				finder7.setMatchKey("lastActionTime");
				finder8.setMatchKey("status");
				finder9.setMatchKey("ackData");
				try {
					while(!finder1.isEnd())
					{
						parser1.parse(response, finder1, true);
						parser2.parse(response, finder2, true);
						parser3.parse(response, finder3, true);
						parser4.parse(response, finder4, true);
						parser5.parse(response, finder5, true);
						parser6.parse(response, finder6, true);
						parser7.parse(response, finder7, true);
						parser8.parse(response, finder8, true);
						parser9.parse(response, finder9, true);
      						if(finder1.isFound())
						{
							finder1.setFound(false);
							String msgid = (String)finder1.getValue();
							String toAddress = (String)finder2.getValue();
							String fromAddress = (String)finder3.getValue();
							String ecSubject = (String)finder4.getValue();
							byte[] bdcSubject = Base64.decodeBase64(ecSubject);
							String subject = new String(bdcSubject, "UTF-8");
							String ecMessage = (String)finder5.getValue();
							long encodingTypel = (long)finder6.getValue();
							int encodingType = (int)encodingTypel;
							long receivedTime = (long)finder7.getValue();
							String status = (String)finder8.getValue();
							String ackdata = (String)finder9.getValue();
							if (!msgid.equals(""))
							{
								try {
						 			String INSERT_RECORD = "UPDATE bm_mail SET msgid=? WHERE ackdata=?";
									PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
									pstmt.setString(1, msgid);
									pstmt.setString(2, ackdata);
									int d = pstmt.executeUpdate();
							       		if (d == -1) {
										System.out.println("db error : " );
									} else {
										APIcall apicall2 = new APIcall();
										String xml2 = "<?xml version='1.0'?><methodCall><methodName>trashMessage</methodName><params><param><value><string>" + msgid + "</string></value></param></params></methodCall>";
										String apiout = apicall2.getAPIcall(xml2);
									}
							        	pstmt.close();
								} catch (SQLException ex3) {
									ex3.printStackTrace();
								}
							}
						} else {
							finder1.endJSON();
						}
					}
				} catch(ParseException pe) {
					pe.printStackTrace();
				}

				}
   			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}


	static class FollowersProcessor {

		private Node nNode2;
		private String fromAddress = "";
		private long receivedTime = 0;
		private String inMessage = "";

		public FollowersProcessor(String fromAddress, long receivedTime, Node nNode2, String inMessage)
		{
			this.fromAddress = fromAddress;
			this.receivedTime = receivedTime;
			this.nNode2 = nNode2;
			this.inMessage = inMessage;
		}

		public Boolean process()
		{
			Boolean processed = false;
			String verb = "";
			String id = "";
			if (nNode2.getNodeType() == Node.ELEMENT_NODE)
			{
				Element eElement = (Element) nNode2;
				verb = eElement.getElementsByTagName("verb").item(0).getTextContent();
				Node targetNode = eElement.getElementsByTagName("target").item(0);
				Element targetElement = (Element) targetNode;
				id = targetElement.getElementsByTagName("id").item(0).getTextContent();
			}
			System.out.println("Processing follower message");
			if (verb.equals("follow"))
			{
				System.out.println("Follower message verb follow");
				int mcount = 0;
				String csql = "SELECT COUNT(*) AS rowcount FROM bm_profiles WHERE address=?";
				try {
					PreparedStatement pstmt = db.conn.prepareStatement(csql);
					pstmt.setString(1, fromAddress);
					ResultSet rs = pstmt.executeQuery();
					rs.next();
					mcount = rs.getInt(1);
//					System.out.println(mcount);
					pstmt.close();
				} catch (SQLException ex3) {
					ex3.printStackTrace();
				}
				if (mcount == 0)
				{
					mcount = 0;
					csql = "SELECT COUNT(*) AS rowcount FROM bm_table WHERE msgid=?";
					try {
						PreparedStatement pstmt = db.conn.prepareStatement(csql);
						pstmt.setString(1, id);
						ResultSet rs = pstmt.executeQuery();
						rs.next();
						mcount = rs.getInt(1);
//						System.out.println(mcount);
						pstmt.close();
					} catch (SQLException ex3) {
						ex3.printStackTrace();
					}
					if (mcount == 0)
					{
						System.out.println("Address not found in profiles - creating");
						try {
							String INSERT_RECORD = "INSERT INTO bm_profiles(address,follower,following,dtstamp) VALUES(?,?,?,?,?)";
							PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
							pstmt.setString(1, fromAddress);
							pstmt.setBoolean(2, true);
							pstmt.setBoolean(3, false);
							java.sql.Timestamp  sqlDate = new java.sql.Timestamp(receivedTime*1000L);
							System.out.println(sqlDate);
							pstmt.setTimestamp(4, sqlDate);
							int i = pstmt.executeUpdate();
							if (i == -1) {
								System.out.println("db error : " );
							}
							pstmt.close();
						} catch (SQLException e) {
							e.printStackTrace();
						}	

						System.out.println("Message not seen before adding message to bm_table");
						try {
							String INSERT_RECORD = "INSERT INTO bm_table(msgid,address,application,message,dtstamp) VALUES(?,?,?,?,?)";
							PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
							pstmt.setString(1, id);
							pstmt.setString(2, fromAddress);
							pstmt.setString(3, "followers");
							pstmt.setString(4, inMessage);
							java.sql.Timestamp  sqlDate = new java.sql.Timestamp(receivedTime*1000L);
							System.out.println(sqlDate);
							pstmt.setTimestamp(5, sqlDate);
							int i = pstmt.executeUpdate();
							if (i == -1) {
								System.out.println("db error : " );
							}
							pstmt.close();
						} catch (SQLException e) {
							e.printStackTrace();
						}
					}
					processed = true;
				} else {
					System.out.println("Address found in profiles - processing");
					mcount = 0;
					csql = "SELECT COUNT(*) AS rowcount FROM bm_profiles WHERE address=? AND follower=?";
					try {
						PreparedStatement pstmt = db.conn.prepareStatement(csql);
						pstmt.setString(1, fromAddress);
						pstmt.setBoolean(2, false);
						ResultSet rs = pstmt.executeQuery();
						rs.next();
						mcount = rs.getInt(1);
						pstmt.close();
					} catch (SQLException ex3) {
						ex3.printStackTrace();
					}
					if (mcount == 1)
					{
						mcount = 0;
						csql = "SELECT COUNT(*) AS rowcount FROM bm_table WHERE msgid=?";
						try {
							PreparedStatement pstmt = db.conn.prepareStatement(csql);
							pstmt.setString(1, id);
							ResultSet rs = pstmt.executeQuery();
							rs.next();
							mcount = rs.getInt(1);
//							System.out.println(mcount);
							pstmt.close();
						} catch (SQLException ex3) {
							ex3.printStackTrace();
						}
						if (mcount == 0)
						{
							System.out.println("Address not a follower - updating to be");
							Follower follower = new Follower(fromAddress);
							follower.followed();

							System.out.println("Message not seen before adding message to bm_table");
							try {
								String INSERT_RECORD = "INSERT INTO bm_table(msgid,address,application,message,dtstamp) VALUES(?,?,?,?,?)";
								PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
								pstmt.setString(1, id);
								pstmt.setString(2, fromAddress);
								pstmt.setString(3, "followers");
								pstmt.setString(4, inMessage);
								java.sql.Timestamp  sqlDate = new java.sql.Timestamp(receivedTime*1000L);
								System.out.println(sqlDate);
								pstmt.setTimestamp(5, sqlDate);
								int i = pstmt.executeUpdate();
								if (i == -1) {
									System.out.println("db error : " );
								}
								pstmt.close();
							} catch (SQLException e) {
								e.printStackTrace();
							}
						}
						processed = true;
					}
				}
			}
			if (verb.equals("unfollow"))
			{
				System.out.println("Follower message verb unfollow");
				int mcount = 0;
				String csql = "SELECT COUNT(*) AS rowcount FROM bm_profiles WHERE address=? AND follower=?";
				try {
					PreparedStatement pstmt = db.conn.prepareStatement(csql);
					pstmt.setString(1, fromAddress);
					pstmt.setBoolean(2, true);
					ResultSet rs = pstmt.executeQuery();
					rs.next();
					mcount = rs.getInt(1);
//					System.out.println(mcount);
					pstmt.close();
				} catch (SQLException ex3) {
					ex3.printStackTrace();
				}
				if (mcount == 1)
				{
					System.out.println("Address is a follower - updating to not be");
					Follower follower = new Follower(fromAddress);
					follower.unfollowed();	
				}
				mcount = 0;
				csql = "SELECT COUNT(*) AS rowcount FROM bm_table WHERE msgid=?";
				try {
					PreparedStatement pstmt = db.conn.prepareStatement(csql);
					pstmt.setString(1, id);
					ResultSet rs = pstmt.executeQuery();
					rs.next();
					mcount = rs.getInt(1);
//					System.out.println(mcount);
					pstmt.close();
				} catch (SQLException ex3) {
					ex3.printStackTrace();
				}
				System.out.println("mcount " + mcount);
				if (mcount == 0)
				{
					System.out.println("Message not seen before adding message to bm_table");
					try {
						String INSERT_RECORD = "INSERT INTO bm_table(msgid,address,application,message,dtstamp) VALUES(?,?,?,?,?)";
						PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
						pstmt.setString(1, id);
						pstmt.setString(2, fromAddress);
						pstmt.setString(3, "followers");
						pstmt.setString(4, inMessage);
						java.sql.Timestamp  sqlDate = new java.sql.Timestamp(receivedTime*1000L);
						pstmt.setTimestamp(5, sqlDate);
						int i = pstmt.executeUpdate();
						if (i == -1) {
							System.out.println("db error : " );
						}
						pstmt.close();
					} catch (SQLException e) {
						e.printStackTrace();
					}
				}
				processed = true;
			}
			return processed;
		}

	}

	static class NewsProcessor {

		private Node nNode2;
		private String fromAddress = "";
		private long receivedTime = 0;
		private String inMessage = "";

		public NewsProcessor(String fromAddress, long receivedTime, Node nNode2, String inMessage)
		{
			this.fromAddress = fromAddress;
			this.receivedTime = receivedTime;
			this.nNode2 = nNode2;
			this.inMessage = inMessage;
		}

		public Boolean process()
		{
			Boolean processed = false;
			String verb = "";
			String id = "";
			String object = "";
			String postactor = "";
			if (nNode2.getNodeType() == Node.ELEMENT_NODE)
			{
				Element eElement = (Element) nNode2;
				verb = eElement.getElementsByTagName("verb").item(0).getTextContent();
				object = eElement.getElementsByTagName("object").item(0).getTextContent();
				Node targetNode = eElement.getElementsByTagName("target").item(0);
				Element targetElement = (Element) targetNode;
				id = targetElement.getElementsByTagName("id").item(0).getTextContent();
				Node actorNode = eElement.getElementsByTagName("actor").item(0);
				Element actorElement = (Element) actorNode;
				postactor = actorElement.getElementsByTagName("id").item(0).getTextContent();
			}
			if (verb.equals("post"))
			{
				int mcount = 0;
				String csql = "SELECT COUNT(*) AS rowcount FROM bm_table WHERE msgid=?";
				try {
					PreparedStatement pstmt = db.conn.prepareStatement(csql);
					pstmt.setString(1, id);
					ResultSet rs = pstmt.executeQuery();
					rs.next();
					mcount = rs.getInt(1);
					pstmt.close();
				} catch (SQLException ex3) {
					ex3.printStackTrace();
				}
				if (mcount == 0)
				{
					int count = 0;
					String csql2 = "SELECT COUNT(*) AS rowcount FROM bm_profiles WHERE address=? AND following=?";
					try {
						PreparedStatement pstmt = db.conn.prepareStatement(csql2);
						pstmt.setString(1, fromAddress);
						pstmt.setBoolean(2, true);
						ResultSet rs = pstmt.executeQuery();
						rs.next();
						count = rs.getInt(1);
//						System.out.println(count);
						pstmt.close();
					} catch (SQLException ex3) {
						ex3.printStackTrace();
					}
					boolean containsHashTag = false;
					if (count == 0)
					{
						Element eElementa = (Element) nNode2;
						Node objectNode = eElementa.getElementsByTagName("object").item(0);
						Element objectElement = (Element) objectNode;
						String postContent = objectElement.getElementsByTagName("content").item(0).getTextContent();
						try {
							String query = "SELECT value FROM bm_settings WHERE setting='hashtag'";
							ResultSet dbq = db.query(query);
							Object o = null;
							for (; dbq.next(); ) {
								o = dbq.getObject(1);
								String hashtag = (String)o;
								hashtag = hashtag + " ";
								if (postContent.indexOf(hashtag) > -1)
								{
									containsHashTag = true;
								}
							}
							db.st.close();
						} catch (SQLException ex3) {
							ex3.printStackTrace();
						} 
					}
					System.out.println("Contains hashtag: " + containsHashTag);
					bmasAddresses bmasaddresses = new bmasAddresses();
					String useraddress = bmasaddresses.getUser();
					if ((count == 1) || (containsHashTag) || useraddress.equals(fromAddress))
					{
						try {
							String INSERT_RECORD = "INSERT INTO bm_table(msgid,address,application,message,dtstamp) VALUES(?,?,?,?,?)";
							PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
							pstmt.setString(1, id);
							pstmt.setString(2, fromAddress);
							pstmt.setString(3, "news");
							pstmt.setString(4, inMessage);
							java.sql.Timestamp  sqlDate = new java.sql.Timestamp(receivedTime*1000L);
							pstmt.setTimestamp(5, sqlDate);
							int i = pstmt.executeUpdate();
							if (i == -1) {
								System.out.println("db error : " );
							}
							pstmt.close();
						} catch	(SQLException e) {
							e.printStackTrace();
						}
					}
				}
				processed = true;	
			}
			if (verb.equals("comment"))
			{
				System.out.println("Processing Comment");
				Element eElementa = (Element) nNode2;
				Node objectNode = eElementa.getElementsByTagName("object").item(0);
				Element objectElement = (Element) objectNode;
				String inReplyTo = objectElement.getElementsByTagName("inReplyTo").item(0).getTextContent();
				String commentID = objectElement.getElementsByTagName("id").item(0).getTextContent();
				String commentContent = objectElement.getElementsByTagName("content").item(0).getTextContent();
				try {
					String query = "SELECT message FROM bm_table WHERE msgid='" + id + "'";
					ResultSet dbq = db.query(query);
					Object o = null;
					for (; dbq.next(); ) {
						o = dbq.getObject(1);
						String message = o.toString();
						try {
							DocumentBuilderFactory dbFactory2 = DocumentBuilderFactory.newInstance();
							DocumentBuilder dBuilder2 = dbFactory2.newDocumentBuilder();
							Document doc2 = dBuilder2.parse(new ByteArrayInputStream(message.getBytes()));
							doc2.getDocumentElement().normalize();
							NodeList nList2 = doc2.getElementsByTagName("activity");
							for (int temp2 = 0; temp2 < nList2.getLength(); temp2++)
							{
								Node nNode2 = nList2.item(temp2);
								if (nNode2.getNodeType() == Node.ELEMENT_NODE)
								{
									Element eElement = (Element) nNode2;
									NodeList objectNodeList = eElement.getElementsByTagName("object");
									for (int temp3 = 0; temp3 < objectNodeList.getLength(); temp3++)
									{
										Node objectCNode = objectNodeList.item(temp3);
										if (objectCNode.getNodeType() == Node.ELEMENT_NODE)
										{
											Element cElement = (Element) objectCNode;
											if (id.equals(inReplyTo))
											{
												System.out.println("Object in reply to found");
												NodeList objectCNodeList = cElement.getElementsByTagName("comments");
												if (objectCNodeList.getLength() == 0)
												{
													Element comments = doc2.createElement("comments");
													Element commentcount = doc2.createElement("totalItems");
													commentcount.appendChild(doc2.createTextNode("0"));
													Element commentItems = doc2.createElement("items");
													comments.appendChild(commentcount);
													comments.appendChild(commentItems);
													objectCNode.appendChild(comments);
												}
												Node commentsN = cElement.getElementsByTagName("comments").item(0);
												Element commentsE = (Element) commentsN;
												Node commentCountN = commentsE.getElementsByTagName("totalItems").item(0);
												Element commentCountE = (Element) commentCountN;
												Node commentItemsN = commentsE.getElementsByTagName("items").item(0);
												Element commentItemsE = (Element) commentItemsN;
												NodeList commentItemL = commentItemsE.getChildNodes();
												int found = 0;
												for (int itemno = 0; itemno < commentItemL.getLength(); itemno++)
												{
													Node itemN = commentItemL.item(itemno);
													Element itemE = (Element) itemN;
													NodeList itemNL = itemE.getChildNodes();
													for (int itemno2 = 0; itemno2 < itemNL.getLength(); itemno2++)
													{
														Node cnode = itemNL.item(itemno2);
														if (cnode.getNodeName().equals("id"))
														{
															String itemid = itemNL.item(itemno2).getTextContent();
															if (itemid.equals(commentID))
															{
																found++;
															}
														}
													}
												}
												if (found > 0)
												{
													System.out.println("Comment has been previously processed");
													processed = true;
												}
												if (!processed)
												{
													System.out.println("Comment has not been previously processed");
													int commentCount = Integer.parseInt(commentsE.getElementsByTagName("totalItems").item(0).getTextContent());
													commentCount = commentCount + 1;
													commentCountN.setTextContent(Integer.toString(commentCount));
													Element commentItem = doc2.createElement("item");
													Element actorItem = doc2.createElement("actor");
													Element objectTypeItem = doc2.createElement("objectType");
													objectTypeItem.appendChild(doc2.createTextNode("person"));
													Element actorIdItem = doc2.createElement("id");
													actorIdItem.appendChild(doc2.createTextNode(fromAddress));
													actorItem.appendChild(objectTypeItem);
													actorItem.appendChild(actorIdItem);
													Element idItem = doc2.createElement("id");
													idItem.appendChild(doc2.createTextNode(commentID));
													Element inReplyToItem = doc2.createElement("inReplyTo");
													inReplyToItem.appendChild(doc2.createTextNode(inReplyTo));
													Element contentItem = doc2.createElement("content");
													contentItem.appendChild(doc2.createTextNode(commentContent));
													commentItem.appendChild(actorItem);
													commentItem.appendChild(idItem);
													commentItem.appendChild(inReplyToItem);
													commentItem.appendChild(contentItem);
													commentItemsE.appendChild(commentItem);
													bmasAddresses bmasaddresses = new bmasAddresses();
													String useraddress = bmasaddresses.getUser();
													if ((!useraddress.equals(fromAddress)) && (useraddress.equals(postactor)))
													{
														try {
															String msg = fromAddress + " commented on your post";
															String INSERT_RECORD = "INSERT INTO bm_alerts(msgid,message,dtstamp) VALUES(?,?,?)";
															PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
															pstmt.setString(1, id);
															pstmt.setString(2, msg);
															java.sql.Timestamp  sqlDate = new java.sql.Timestamp(receivedTime*1000L);
															pstmt.setTimestamp(3, sqlDate);
															int i = pstmt.executeUpdate();
															if (i == -1) {
																System.out.println("db error : " );
															}
															pstmt.close();
														} catch (SQLException ex3) {
															ex3.printStackTrace();
														}
													}	
													processed = true;
												} 
											} else {
												NodeList commentsNL = cElement.getElementsByTagName("comments");
												if (commentsNL.getLength() > 0)
												{				
													Node commentsN = cElement.getElementsByTagName("comments").item(0);
													Element commentsE = (Element) commentsN;
													Node commentCountN = commentsE.getElementsByTagName("totalItems").item(0);
													Element commentCountE = (Element) commentCountN;
													Node commentItemsN = commentsE.getElementsByTagName("items").item(0);
													Element commentItemsE = (Element) commentItemsN;
													NodeList commentItemL = commentItemsE.getChildNodes();
													for (int itemno = 0; itemno < commentItemL.getLength() && !processed; itemno++)
													{
														Node itemo = commentItemL.item(itemno);
														processed = processComment(processed, itemo, doc2, commentID, inReplyTo, commentContent, id);
													}
												}
											}
										}
									}
								}
							}
							TransformerFactory tf = TransformerFactory.newInstance();
							Transformer transformer = tf.newTransformer();
//							transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
//							transformer.setOutputProperty(OutputKeys.CDATA-SECTION-ELEMENTS, "content");
							StringWriter writer = new StringWriter();
							transformer.transform(new DOMSource(doc2), new StreamResult(writer));
							String output = writer.getBuffer().toString();
							try {
								String INSERT_RECORD = "UPDATE bm_table SET message=? WHERE msgid=?";
								PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
								pstmt.setString(1, output);
								pstmt.setString(2, id);
								int i = pstmt.executeUpdate();
								if (i == -1) {
									System.out.println("db error : " );
								}
								pstmt.close();
							} catch (SQLException ex3) {
								ex3.printStackTrace();
							}
   						} catch (Exception e) {
							e.printStackTrace();
						}
					}
					db.st.close();
				} catch (SQLException ex3) {
					ex3.printStackTrace();
				}
			}
			if (verb.equals("like"))
			{
				System.out.println("Processing Like");
				Element eElementa = (Element) nNode2;
				Node objectNode = eElementa.getElementsByTagName("object").item(0);
				Element objectElement = (Element) objectNode;
				String inReplyTo = objectElement.getElementsByTagName("inReplyTo").item(0).getTextContent();
				String likeID = objectElement.getElementsByTagName("id").item(0).getTextContent();
				try {
					String query = "SELECT message FROM bm_table WHERE msgid='" + id + "'";
					ResultSet dbq = db.query(query);
					Object o = null;
					for (; dbq.next(); ) {
						o = dbq.getObject(1);
						String message = o.toString();
						try {
							DocumentBuilderFactory dbFactory2 = DocumentBuilderFactory.newInstance();
							DocumentBuilder dBuilder2 = dbFactory2.newDocumentBuilder();
							Document doc2 = dBuilder2.parse(new ByteArrayInputStream(message.getBytes()));
							doc2.getDocumentElement().normalize();
							NodeList nList2 = doc2.getElementsByTagName("activity");
							String totalItems = "";
							String item = "";
							for (int temp2 = 0; temp2 < nList2.getLength(); temp2++)
							{
								Node nNode2 = nList2.item(temp2);
								if (nNode2.getNodeType() == Node.ELEMENT_NODE)
								{
									Element eElement = (Element) nNode2;
									NodeList objectNodeList = eElement.getElementsByTagName("object");
									for (int temp3 = 0; temp3 < objectNodeList.getLength(); temp3++)
									{
										Node objectCNode = objectNodeList.item(temp3);
										if (objectCNode.getNodeType() == Node.ELEMENT_NODE)
										{
											Element cElement = (Element) objectCNode;
											if (id.equals(inReplyTo))
											{
												System.out.println("Object in reply to found");
												NodeList objectCNodeList = cElement.getElementsByTagName("likes");
												if (objectCNodeList.getLength() == 0)
												{
													Element likes = doc2.createElement("likes");
													Element likecount = doc2.createElement("totalItems");
													likecount.appendChild(doc2.createTextNode("0"));
													Element likeItems = doc2.createElement("items");
													likes.appendChild(likecount);
													likes.appendChild(likeItems);
													objectCNode.appendChild(likes);
												}
												Node likesN = cElement.getElementsByTagName("likes").item(0);
												Element likesE = (Element) likesN;
												Node likeCountN = likesE.getElementsByTagName("totalItems").item(0);
												Element likeCountE = (Element) likeCountN;
												Node likeItemsN = likesE.getElementsByTagName("items").item(0);
												Element likeItemsE = (Element) likeItemsN;
												NodeList likeItemL = likeItemsE.getChildNodes();
												int found = 0;
												for (int temp4 = 0; temp4 < likeItemL.getLength(); temp4++)
												{
													Node itemN = likeItemL.item(temp4);
													Element itemE = (Element) itemN;
													Node actorN = itemE.getElementsByTagName("actor").item(0);
													Element actorE = (Element) actorN;
													String liker = actorE.getElementsByTagName("id").item(0).getTextContent();
													System.out.println("Previous liker " + liker + " comparing to " + fromAddress);
													if (liker.equals(fromAddress))
													{
														System.out.println("Liked by Address previously");
														found++;
													}
													NodeList itemNL = itemE.getChildNodes();
													for (int itemno2 = 0; itemno2 < itemNL.getLength(); itemno2++)
													{
														Node cnode = itemNL.item(itemno2);
														if (cnode.getNodeName().equals("id"))
														{
															String itemid = itemNL.item(itemno2).getTextContent();
															System.out.println("Previous itemid " + itemid + " comparing to " + likeID);
															if (itemid.equals(likeID))
															{
																System.out.println("Previously processed itemid " + itemid);
																found++;
															}
														}
													}

												}
												if (found > 0)
												{
													System.out.println("Like has been previously processed");
													processed = true;
												}
												if (found == 0)
												{
													System.out.println("Like has not been previously processed");
													int likeCount = Integer.parseInt(likesE.getElementsByTagName("totalItems").item(0).getTextContent());
													likeCount = likeCount + 1;
													likeCountN.setTextContent(Integer.toString(likeCount));
													Element likeItem = doc2.createElement("item");
													Element actorItem = doc2.createElement("actor");
													Element objectTypeItem = doc2.createElement("objectType");
													objectTypeItem.appendChild(doc2.createTextNode("person"));
													Element actorIdItem = doc2.createElement("id");
													actorIdItem.appendChild(doc2.createTextNode(fromAddress));
													actorItem.appendChild(objectTypeItem);
													actorItem.appendChild(actorIdItem);
													Element idItem = doc2.createElement("id");
													idItem.appendChild(doc2.createTextNode(likeID));
													Element inReplyToItem = doc2.createElement("inReplyTo");
													inReplyToItem.appendChild(doc2.createTextNode(inReplyTo));
													likeItem.appendChild(actorItem);
													likeItem.appendChild(idItem);
													likeItem.appendChild(inReplyToItem);
													likeItemsE.appendChild(likeItem);
													bmasAddresses bmasaddresses = new bmasAddresses();
													String useraddress = bmasaddresses.getUser();
													if ((!useraddress.equals(fromAddress)) && (useraddress.equals(postactor)))
													{
														try {
															String msg = fromAddress + " liked your post";
															String INSERT_RECORD = "INSERT INTO bm_alerts(msgid,message,dtstamp) VALUES(?,?,?)";
															PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
															pstmt.setString(1, id);
															pstmt.setString(2, msg);
															java.sql.Timestamp  sqlDate = new java.sql.Timestamp(receivedTime*1000L);
															pstmt.setTimestamp(3, sqlDate);
															int i = pstmt.executeUpdate();
															if (i == -1) {
																System.out.println("db error : " );
															}
															pstmt.close();
														} catch (SQLException ex3) {
															ex3.printStackTrace();
														}
													}	
													processed = true;
												}
											} else {
												NodeList objectCNodeList = cElement.getElementsByTagName("comments");
												if (objectCNodeList.getLength() != 0)
												{
													Node commentsN = cElement.getElementsByTagName("comments").item(0);
													Element commentsE = (Element) commentsN;
													Node commentCountN = commentsE.getElementsByTagName("totalItems").item(0);
													Element commentCountE = (Element) commentCountN;
													Node commentItemsN = commentsE.getElementsByTagName("items").item(0);
													Element commentItemsE = (Element) commentItemsN;
													NodeList commentItemL = commentItemsE.getChildNodes();
													for (int z = 0; z<commentItemL.getLength() && !processed; z++)
													{
														Node itemo = commentItemL.item(z);
														processed = processLike(processed, itemo, doc2, likeID, inReplyTo, id);
													}
												}
											}
										}
									}
								}
							}
							TransformerFactory tf = TransformerFactory.newInstance();
							Transformer transformer = tf.newTransformer();
//							transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
							StringWriter writer = new StringWriter();
							transformer.transform(new DOMSource(doc2), new StreamResult(writer));
							String output = writer.getBuffer().toString();
							try {
								String INSERT_RECORD = "UPDATE bm_table SET message=? WHERE msgid=?";
								PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
								pstmt.setString(1, output);
								pstmt.setString(2, id);
								int i = pstmt.executeUpdate();
								if (i == -1) {
									System.out.println("db error : " );
								}
								pstmt.close();
							} catch (SQLException ex3) {
								ex3.printStackTrace();
							}
   						} catch (Exception e) {
							e.printStackTrace();
						}
					}
					db.st.close();
				} catch (SQLException ex3) {
					ex3.printStackTrace();
				} 
				
			}
			return processed;
		}

		public Boolean processComment(Boolean processed, Node objectCNode, Document doc2, String commentID, String inReplyTo, String commentContent, String msgid)
		{
			String id = "";
			NodeList objectCNodeNL = objectCNode.getChildNodes();
			for (int i = 0; i<objectCNodeNL.getLength(); i++)
			{
				Node cnode = objectCNodeNL.item(i);
				if (cnode.getNodeName().equals("id"))
				{
					id = cnode.getTextContent();
				}
			}
			Element cElement = (Element) objectCNode;
			Node actorNode = cElement.getElementsByTagName("actor").item(0);
			Element actorElement = (Element) actorNode;
			String postactor = actorElement.getElementsByTagName("id").item(0).getTextContent();
			if (id.equals(inReplyTo))
			{
				System.out.println("Object in reply to found");
				NodeList objectCNodeList = cElement.getElementsByTagName("comments");
				if (objectCNodeList.getLength() == 0)
				{
					Element comments = doc2.createElement("comments");
					Element commentcount = doc2.createElement("totalItems");
					commentcount.appendChild(doc2.createTextNode("0"));
					Element commentItems = doc2.createElement("items");
					comments.appendChild(commentcount);
					comments.appendChild(commentItems);
					objectCNode.appendChild(comments);
				}
				Node commentsN = cElement.getElementsByTagName("comments").item(0);
				Element commentsE = (Element) commentsN;
				Node commentCountN = commentsE.getElementsByTagName("totalItems").item(0);
				Element commentCountE = (Element) commentCountN;
				Node commentItemsN = commentsE.getElementsByTagName("items").item(0);
				Element commentItemsE = (Element) commentItemsN;
				NodeList commentItemL = commentItemsE.getChildNodes();
				int found = 0;
				for (int itemno = 0; itemno < commentItemL.getLength(); itemno++)
				{
					Node itemN = commentItemL.item(itemno);
					Element itemE = (Element) itemN;
					NodeList itemNL = itemE.getChildNodes();
					for (int itemno2 = 0; itemno2 < itemNL.getLength(); itemno2++)
					{
						Node cnode = itemNL.item(itemno2);
						if (cnode.getNodeName().equals("id"))
						{
							String itemid = itemNL.item(itemno2).getTextContent();
							if (itemid.equals(commentID))
							{
								found++;
							}
						}
					}
				}
				if (found > 0)
				{
					System.out.println("Comment has been previously processed");
					processed = true;
				}
				if (!processed)
				{
					System.out.println("Comment has not been previously processed");
					int commentCount = Integer.parseInt(commentsE.getElementsByTagName("totalItems").item(0).getTextContent());
					commentCount = commentCount + 1;
					commentCountN.setTextContent(Integer.toString(commentCount));
					Element commentItem = doc2.createElement("item");
					Element actorItem = doc2.createElement("actor");
					Element objectTypeItem = doc2.createElement("objectType");
					objectTypeItem.appendChild(doc2.createTextNode("person"));
					Element actorIdItem = doc2.createElement("id");
					actorIdItem.appendChild(doc2.createTextNode(fromAddress));
					actorItem.appendChild(objectTypeItem);
					actorItem.appendChild(actorIdItem);
					Element idItem = doc2.createElement("id");
					idItem.appendChild(doc2.createTextNode(commentID));
					Element inReplyToItem = doc2.createElement("inReplyTo");
					inReplyToItem.appendChild(doc2.createTextNode(inReplyTo));
					Element contentItem = doc2.createElement("content");
					contentItem.appendChild(doc2.createTextNode(commentContent));
					commentItem.appendChild(actorItem);
					commentItem.appendChild(idItem);
					commentItem.appendChild(inReplyToItem);
					commentItem.appendChild(contentItem);
					commentItemsE.appendChild(commentItem);
					bmasAddresses bmasaddresses = new bmasAddresses();
					String useraddress = bmasaddresses.getUser();
					if ((!useraddress.equals(fromAddress)) && (useraddress.equals(postactor)))
					{
						try {
							String msg = fromAddress + " commented on your comment";
							String INSERT_RECORD = "INSERT INTO bm_alerts(msgid,message,dtstamp) VALUES(?,?,?)";
							PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
							pstmt.setString(1, msgid);
							pstmt.setString(2, msg);
							java.sql.Timestamp  sqlDate = new java.sql.Timestamp(receivedTime*1000L);
							pstmt.setTimestamp(3, sqlDate);
							int i = pstmt.executeUpdate();
							if (i == -1) {
								System.out.println("db error : " );
							}
							pstmt.close();
						} catch (SQLException ex3) {
							ex3.printStackTrace();
						}
					}	
					processed = true;
				}
			} else {
				NodeList commentsNL = cElement.getElementsByTagName("comments");
				if (commentsNL.getLength() > 0)
				{				
					Node commentsN = cElement.getElementsByTagName("comments").item(0);
					Element commentsE = (Element) commentsN;
					Node commentCountN = commentsE.getElementsByTagName("totalItems").item(0);
					Element commentCountE = (Element) commentCountN;
					Node commentItemsN = commentsE.getElementsByTagName("items").item(0);
					Element commentItemsE = (Element) commentItemsN;
					NodeList commentItemL = commentItemsE.getChildNodes();
					for (int itemno = 0; itemno < commentItemL.getLength() && !processed; itemno++)
					{
						Node itemo = commentItemL.item(itemno);
						Boolean processedo = processComment(processed, itemo, doc2, commentID, inReplyTo, commentContent, msgid);
						processed = processedo;
					}
				}
			}
			return processed;
		}

		public Boolean processLike(Boolean processed, Node objectCNode, Document doc2, String likeID, String inReplyTo, String msgid)
		{
			String id = "";
			NodeList objectCNodeNL = objectCNode.getChildNodes();
			for (int i = 0; i<objectCNodeNL.getLength(); i++)
			{
				Node cnode = objectCNodeNL.item(i);
				if (cnode.getNodeName().equals("id"))
				{
					id = cnode.getTextContent();
				}
			}
			Element cElement = (Element) objectCNode;
			Node actorNode = cElement.getElementsByTagName("actor").item(0);
			Element actorElement = (Element) actorNode;
			String postactor = actorElement.getElementsByTagName("id").item(0).getTextContent();
			if (id.equals(inReplyTo))
			{
				NodeList objectCNodeList = cElement.getElementsByTagName("likes");
				if (objectCNodeList.getLength() == 0)
				{
					Element likes = doc2.createElement("likes");
					Element likecount = doc2.createElement("totalItems");
					likecount.appendChild(doc2.createTextNode("0"));
					Element likeItems = doc2.createElement("items");
					likes.appendChild(likecount);
					likes.appendChild(likeItems);
					objectCNode.appendChild(likes);
				}
				Node likesN = cElement.getElementsByTagName("likes").item(0);
				Element likesE = (Element) likesN;
				Node likeCountN = likesE.getElementsByTagName("totalItems").item(0);
				Element likeCountE = (Element) likeCountN;
				Node likeItemsN = likesE.getElementsByTagName("items").item(0);
				Element likeItemsE = (Element) likeItemsN;
				NodeList likeItemL = likeItemsE.getChildNodes();
				int found = 0;
				for (int temp4 = 0; temp4 < likeItemL.getLength(); temp4++)
				{
					Node itemN = likeItemL.item(temp4);
					Element itemE = (Element) itemN;
					Node actorN = itemE.getElementsByTagName("actor").item(0);
					Element actorE = (Element) actorN;
					String liker = actorE.getElementsByTagName("id").item(0).getTextContent();
					System.out.println("Previous liker " + liker + " comparing to " + fromAddress);
					if (liker.equals(fromAddress))
					{
						System.out.println("Liked by address previously");
						found++;
					}
					NodeList itemNL = itemE.getChildNodes();
					for (int itemno2 = 0; itemno2 < itemNL.getLength(); itemno2++)
					{
						Node cnode = itemNL.item(itemno2);
						if (cnode.getNodeName().equals("id"))
						{
							String itemid = itemNL.item(itemno2).getTextContent();
							System.out.println("Previous itemid " + itemid + " comparing to " + likeID);
							if (itemid.equals(likeID))
							{
								System.out.println("Previously processed itemid");
								found++;
							}
						}
					}
				}
				if (found > 0)
				{
					System.out.println("Like has been previously processed");
					processed = true;
				}
				if (found == 0)
				{
					System.out.println("Like has not been previously processed");
					int likeCount = Integer.parseInt(likesE.getElementsByTagName("totalItems").item(0).getTextContent());
					likeCount = likeCount + 1;
					likeCountN.setTextContent(Integer.toString(likeCount));
					Element likeItem = doc2.createElement("item");
					Element actorItem = doc2.createElement("actor");
					Element objectTypeItem = doc2.createElement("objectType");
					objectTypeItem.appendChild(doc2.createTextNode("person"));
					Element actorIdItem = doc2.createElement("id");
					actorIdItem.appendChild(doc2.createTextNode(fromAddress));
					actorItem.appendChild(objectTypeItem);
					actorItem.appendChild(actorIdItem);
					Element idItem = doc2.createElement("id");
					idItem.appendChild(doc2.createTextNode(likeID));
					Element inReplyToItem = doc2.createElement("inReplyTo");
					inReplyToItem.appendChild(doc2.createTextNode(inReplyTo));
					likeItem.appendChild(actorItem);
					likeItem.appendChild(idItem);
					likeItem.appendChild(inReplyToItem);
					likeItemsE.appendChild(likeItem);
					bmasAddresses bmasaddresses = new bmasAddresses();
					String useraddress = bmasaddresses.getUser();
					if ((!useraddress.equals(fromAddress)) && (useraddress.equals(postactor)))
					{
						try {
							String msg = fromAddress + " liked your comment";
							String INSERT_RECORD = "INSERT INTO bm_alerts(msgid,message,dtstamp) VALUES(?,?,?)";
							PreparedStatement pstmt = db.conn.prepareStatement(INSERT_RECORD);
							pstmt.setString(1, msgid);
							pstmt.setString(2, msg);
							java.sql.Timestamp  sqlDate = new java.sql.Timestamp(receivedTime*1000L);
							pstmt.setTimestamp(3, sqlDate);
							int i = pstmt.executeUpdate();
							if (i == -1) {
								System.out.println("db error : " );
							}
							pstmt.close();
						} catch (SQLException ex3) {
							ex3.printStackTrace();
						}
					}	
					processed = true;
				}
			} else {
				NodeList objectCNodeList = cElement.getElementsByTagName("comments");
				if (objectCNodeList.getLength() != 0)
				{
					Node commentsN = cElement.getElementsByTagName("comments").item(0);
					Element commentsE = (Element) commentsN;
					Node commentCountN = commentsE.getElementsByTagName("totalItems").item(0);
					Element commentCountE = (Element) commentCountN;
					Node commentItemsN = commentsE.getElementsByTagName("items").item(0);
					Element commentItemsE = (Element) commentItemsN;
					NodeList commentItemL = commentItemsE.getChildNodes();
					for (int z = 0; z<commentItemL.getLength() && !processed; z++)
					{
						Node itemo = commentItemL.item(z);
						processed = processLike(processed, itemo, doc2, likeID, inReplyTo, msgid);
					}
				}
			}
			return processed;
		}


	}


	static class APIcall {

		public APIcall() {
		}

		public String getAPIcall(String xml)
		{
	        	String response = "";
			String bmapi_ip = "";
			String bmapi_port = "";
			String bmapi_user = "";
			String bmapi_password = "";

			try {
				String query = "SELECT value FROM bm_settings WHERE setting='bmapi_ip'";
				ResultSet dbq = db.query(query);
				Object o = null;
				for (; dbq.next(); ) {
					o = dbq.getObject(1);
					bmapi_ip = (String)o;
				}
			} catch (SQLException ex3) {
				ex3.printStackTrace();
			}
			try {
				String query = "SELECT value FROM bm_settings WHERE setting='bmapi_port'";
				ResultSet dbq = db.query(query);
				Object o = null;
				for (; dbq.next(); ) {
					o = dbq.getObject(1);
					bmapi_port = (String)o;
				}
			} catch (SQLException ex3) {
				ex3.printStackTrace();
			}
			try {
				String query = "SELECT value FROM bm_settings WHERE setting='bmapi_user'";
				ResultSet dbq = db.query(query);
				Object o = null;
				for (; dbq.next(); ) {
					o = dbq.getObject(1);
					bmapi_user = (String)o;
				}
			} catch (SQLException ex3) {
				ex3.printStackTrace();
			}
			try {
				String query = "SELECT value FROM bm_settings WHERE setting='bmapi_password'";
				ResultSet dbq = db.query(query);
				Object o = null;
				for (; dbq.next(); ) {
					o = dbq.getObject(1);
					bmapi_password = (String)o;
				}
			} catch (SQLException ex3) {
				ex3.printStackTrace();
			}

			if (bmapi_user.equals("default") && bmapi_password.equals("default"))
			{
				System.out.println("The api user and password are not set");
			}
			String strURL = "http://" + bmapi_ip + ":" + bmapi_port + "/";
			HttpPost post = new HttpPost(strURL);
			try {
				DefaultHttpClient httpclient = new DefaultHttpClient();
				String auth = bmapi_user + ":" + bmapi_password;
				String encoding = Base64.encodeBase64String(auth.getBytes());	
				post.setHeader("Authorization", "Basic " + encoding);
			        StringEntity requestEntity = new StringEntity(xml);
			        post.setEntity(requestEntity);
				HttpResponse result = httpclient.execute(post);
				HttpEntity resulte = result.getEntity();
				String responsestring = EntityUtils.toString(resulte, "UTF-8");
				response = responsestring;
				HttpEntity poster = post.getEntity();
				try {
					EntityUtils.consume(poster);
				} finally {
					post.releaseConnection();
				}
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				post.releaseConnection();
			}
			return response;
		}
	}

	static class StringHash {

		public StringHash()
		{
		}

		public byte[] byteArrayHash(String input) throws NoSuchAlgorithmException {
			MessageDigest sha256 = MessageDigest.getInstance("SHA-256");        
			byte[] inputBytes = input.getBytes();
			byte[] inputHash = sha256.digest(inputBytes);
			return inputHash;
		}

		public String stringHash(String input) throws NoSuchAlgorithmException {
			MessageDigest sha256 = MessageDigest.getInstance("SHA-256");        
			byte[] inputBytes = input.getBytes();
			byte[] inputHash = sha256.digest(inputBytes);
			StringBuffer sb = new StringBuffer();
			for (int i = 0; i < inputHash.length; i++) {
				sb.append(Integer.toString((inputHash[i] & 0xff) + 0x100, 16).substring(1));
			}
 			return sb.toString();
		}


	}

	static class HTMLBuilder {

		private String response = "";

		public HTMLBuilder() {
		}

		public String getHTML()
		{
			return response;
		}

		public void append(String in)
		{
			response = response + in;
		}

		public void appendHTMLHead()
		{
			HTMLHead temp = new HTMLHead();
			response = response + temp.getHTMLHead();
		}

		public void appendHTMLHeadEnd()
		{
			HTMLHeadEnd temp = new HTMLHeadEnd();
			response = response + temp.getHTMLHeadEnd();
		}

		public void appendHTMLHeadEndNews()
		{
			HTMLHeadEndNews temp = new HTMLHeadEndNews();
			response = response + temp.getHTMLHeadEndNews();
		}

		public void appendHTMLStyle()
		{
			HTMLStyle temp = new HTMLStyle();
			response = response + temp.getHTMLStyle();
		}

		public void appendHTMLScript()
		{
			HTMLScript temp = new HTMLScript();
			response = response + temp.getHTMLScript();
		}

		public void appendNAVBar()
		{
			NAVBar temp = new NAVBar();
			response = response + temp.getNAVBar();
		}

		public void appendMainStart()
		{
			MainStart temp = new MainStart();
			response = response + temp.getMainStart();
		}

		public void appendMainLeftMenu()
		{
			MainLeftMenu temp = new MainLeftMenu();
			response = response + temp.getMainLeftMenu();
		}

		public void appendMailLeftMenu()
		{
			MailLeftMenu temp = new MailLeftMenu(db);
			response = response + temp.getMailLeftMenu();
		}

		public void appendProfilesLeftMenu()
		{
			ProfilesLeftMenu temp = new ProfilesLeftMenu(db);
			response = response + temp.getProfilesLeftMenu();
		}

		public void appendSettingsLeftMenu()
		{
			SettingsLeftMenu temp = new SettingsLeftMenu();
			response = response + temp.getSettingsLeftMenu();
		}

		public void appendNewsPostForm()
		{
			NewsPostForm temp = new NewsPostForm();
			response = response + temp.getNewsPostForm();
		}

		public void appendEndDiv()
		{
			EndDiv temp = new EndDiv();
			response = response + temp.getEndDiv();
		}

		public void appendEndBody()
		{
			EndBody temp = new EndBody();
			response = response + temp.getEndBody();
		}

		public void appendDefaultStart()
		{
			appendHTMLHead();
			appendHTMLStyle();
			appendHTMLScript();
			appendHTMLHeadEnd();
			appendNAVBar();
		}

	}

	static class HTMLHead {

		public HTMLHead() {
		}

		public String getHTMLHead()
		{
			String startDoc ="<!DOCTYPE html><html><head><meta charset='utf-8' /><meta http-equiv='X-UA-Compatible' content='IE=8'/><title>BM-ActivityStream</title>";
			return startDoc;
		}
	}

	static class HTMLHeadEnd {

		public HTMLHeadEnd() {
		}

		public String getHTMLHeadEnd()
		{
			String startDoc ="</head><body>";
			return startDoc;
		}
	}

	static class HTMLHeadEndNews {

		public HTMLHeadEndNews() {
		}

		public String getHTMLHeadEndNews()
		{
			String startDoc ="</head><body onload='fillCategory();'>";
			return startDoc;
		}
	}

	static class HTMLStyle {

		public HTMLStyle() {
		}

		public String getHTMLStyle()
		{
			String startDoc ="<style type='text/css'>html, body{    margin:0;    padding:0;}nav{background-color:black;color:white;height:    40px;width: 100%;position: fixed;}nav ul {list-style: none;}nav ul li {margin: 0 14px;}nav ul li a {    display:block;    color: white;    font-weight: 700;    letter-spacing: 0.08em;    text-decoration: none;    text-transform: uppercase;float: left;margin: 0 14px;}nav ul li a.norm {    display:block;    color: white;    font-weight: 700;    letter-spacing: 0.08em;    text-decoration: none;    text-transform: uppercase;float: left;margin: 0 14px;}nav ul li a.red {    display:block;    color: red;    font-weight: 700;    letter-spacing: 0.08em;    text-decoration: none;    text-transform: uppercase;float: left;margin: 0 14px;}nav ul li a.normright {    display:block;    color: white;    font-weight: 700;    letter-spacing: 0.08em;    text-decoration: none;    text-transform: uppercase;    float: right;margin: 0 14px;}#leftmenu {width: 100px;margin-top: 55px;margin-left: 70px;margin-right: 200px;float:    left;position: fixed;}#maincontent {width: 960px;margin-top: 55px;margin-left: 200px;margin-right: 200px;float:    left;}#imagePreview img {  border:1px solid;   display: block;   max-width: 825px;   max-height: 825px;   width; auto;   height; auto;   margin-top: auto;   margin-bottom: auto;   margin-left: 0px;   margin-right: auto;   visibility: hidden;    filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale);} #newsimage img {  border:1px solid;   display: block;   max-width: 825px;   max-height: 825px;   width; auto;   height; auto;   margin-top: auto;   margin-bottom: auto;   margin-left: 0px;   margin-right: auto; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale);} pre {display: block;white-space: pre-wrap;word-wrap: break-word;} #comment{margin-left: 10px;margin-right: 10px;border:1px solid #999;page-break-inside:avoid} #comment_form{margin-left: 10px;margin-right: 10px;page-break-inside:avoid} #post{margin-left: 0px;border:1px solid #999;page-break-inside:avoid}</style>";
			return startDoc;
		}
	}

	static class HTMLScript {

		public HTMLScript() {
		}

		public String getHTMLScript()
		{
			String startDoc ="<script language='javascript'>" +
"function movecomment_form(x,y,z,a,b,c) {" +
"        document.getElementById(x).appendChild(document.getElementById(y));" +
"        var form = document.getElementById(z);" +
"        for (var i = 0, max = form.length; i < max; i++) " +
"        { " +
"            if (form[i].name == 'address') " +
"            { " +
"               form[i].value = a; " +
"            } " +
"            if (form[i].name == 'targetid') " +
"            { " +
"               form[i].value = b; " +
"            } " +
"            if (form[i].name == 'inreplytoid') " +
"            { " +
"               form[i].value = c; " +
"            } " +
"        } " +
"}" +
"function toggle(x) {" +
"        var allInputs = document.getElementsByName(x.name);" +
"        for (var i = 0, max = allInputs.length; i < max; i++) " +
"        { " +
"            if (allInputs[i].type == 'checkbox')" +
"            if (x.checked == true)" +
"                allInputs[i].checked = true; " +
"            else" +
"                allInputs[i].checked = false;" +
"        }" +
"}" +
"function selectAll()" +
"{" +
" var form = document.forms[0];" +
" for (var i=0; i<form.To.length; i++) {" +
" form.To.options[i].selected = true;" +
" }" +
" return true;" +
"}" +
"function fillCategory(){";

			startDoc = startDoc + "var followvar = [";
			try {
				String query = "SELECT address FROM bm_profiles WHERE follower=true ORDER BY dtstamp DESC";
//				System.out.println(query);
				ResultSet dbq = db.query(query);
				Object o = null;
				int count = 0;
				for (; dbq.next(); ) {
					if (count != 0)
					{
						startDoc = startDoc + ", ";
					}
					count++;
					o = dbq.getObject(1);
					String address = (String)o;
					startDoc = startDoc + "'" + address + "'";
				}
				db.st.close();
			} catch (SQLException ex3) {
				ex3.printStackTrace();
			} 
			startDoc = startDoc + "];";

startDoc = startDoc + "     for (var i=0; i < followvar.length;++i){  " +  
"        addOption(document.share.FromLB, followvar[i], followvar[i]);" +
"    }";


startDoc = startDoc + "addOption(document.share.followers, 'Followers', 'Followers', '');" +
"addOption(document.share.followers, 'Lists', 'Lists', '');" +
"addOption(document.share.followers, 'Public', 'Public', '');}" +
"function SelectSubCat()" +
"{removeAllOptions(document.share.FromLB);";
		
			startDoc = startDoc + "var followvar = [";
			try {
				String query = "SELECT address FROM bm_profiles WHERE follower=true ORDER BY dtstamp DESC";
//				System.out.println(query);
				ResultSet dbq = db.query(query);
				Object o = null;
				int count = 0;
				for (; dbq.next(); ) {
					if (count != 0)
					{
						startDoc = startDoc + ", ";
					}
					count++;
					o = dbq.getObject(1);
					String address = (String)o;
					startDoc = startDoc + "'" + address + "'";
				}
				db.st.close();
			} catch (SQLException ex3) {
				ex3.printStackTrace();
			} 
			startDoc = startDoc + "];";

			startDoc = startDoc + "var listsvar = [";
			try {
				String query = "SELECT DISTINCT list FROM bm_profiles_lists";
//				System.out.println(query);
				ResultSet dbq = db.query(query);
				Object o = null;
				int count = 0;
				for (; dbq.next(); ) {
					if (count != 0)
					{
						startDoc = startDoc + ", ";
					}
					count++;
					o = dbq.getObject(1);
					String list = (String)o;
					startDoc = startDoc + "'" + list + "'";
				}
				db.st.close();
			} catch (SQLException ex3) {
				ex3.printStackTrace();
			} 
			startDoc = startDoc + "];";


startDoc = startDoc + "if(document.share.followers.value == 'Followers')" +
"{removeAllOptions(document.share.To);" +
"    for (var i=0; i < followvar.length;++i){  " +  
"        addOption(document.share.FromLB, followvar[i], followvar[i]);" +
"    }" +
"}";

startDoc = startDoc + "if(document.share.followers.value == 'Lists') " +
"{removeAllOptions(document.share.To);" +
"    for (var i=0; i < listsvar.length;++i){    " +
"        addOption(document.share.FromLB, listsvar[i], listsvar[i]);" +
"    }" +
"}";

startDoc = startDoc + "if(document.share.followers.value == 'Public')" +
"{removeAllOptions(document.share.To);" +
"addOption(document.share.FromLB,'Signed', 'Signed');" +
"addOption(document.share.FromLB,'Anonymous', 'Anonymous');}}" +
"function removeAllOptions(selectbox){" +
"	var i;" +
"	for(i=selectbox.options.length-1;i>=0;i--)" +
"	{		selectbox.remove(i);" +
"	}" +
"}" +
"function addOption(selectbox, value, text )" +
"{	var optn = document.createElement('OPTION');" +
"	optn.text = text;" +
"	optn.value = value;" +
"	selectbox.options.add(optn);" +
"}" +
"function move(tbFrom, tbTo)" +
"{ var arrFrom = new Array();" +
" var arrTo = new Array();" +
" var arrLU = new Array();" +
"if(document.share.followers.value == 'Public')" +
"{" +
" if (tbFrom.id != 'To')" +
" {" +
" var zz; for (zz = 0; zz< tbFrom.options.length; zz++)" +
" {" +
"  if (tbFrom.options[zz].selected && tbFrom.options[zz].value== 'Anonymous')" +
"  {" +
"   removeAllOptions(document.share.To);" +
"   removeAllOptions(document.share.FromLB);" +
"   addOption(document.share.FromLB,'Signed', 'Signed');" +
"   addOption(document.share.To,'Anonymous', 'Anonymous');" +
"  }" +
"  if (tbFrom.options[zz].selected && tbFrom.options[zz].value == 'Signed')" +
"  {" +
"   removeAllOptions(document.share.To);" +
"   removeAllOptions(document.share.FromLB);" +
"   addOption(document.share.FromLB,'Anonymous', 'Anonymous');" +
"   addOption(document.share.To,'Signed', 'Signed');" +
"  }" +
" }" +
" }" +
"}" +
" var i; for (i = 0; i < tbTo.options.length; i++)" +
"  {  arrLU[tbTo.options[i].text] = tbTo.options[i].value;" +
"  arrTo[i] = tbTo.options[i].text;" +
" }" +
" var fLength = 0;" +
" var tLength = arrTo.length;" +
" for(i = 0; i < tbFrom.options.length; i++)" +
"  {  arrLU[tbFrom.options[i].text] = tbFrom.options[i].value;" +
"  if (tbFrom.options[i].selected && tbFrom.options[i].value != '')" +
"   {   arrTo[tLength] = tbFrom.options[i].text;" +
"   tLength++;" +
"  }  else   {" +
"   arrFrom[fLength] = tbFrom.options[i].text;" +
"   fLength++;" +
"  }" +
"}" +
"tbFrom.length = 0;" +
"tbTo.length = 0;" +
"var ii;" +
"for(ii = 0; ii < arrFrom.length; ii++)" +
" {  var no = new Option();" +
"  no.value = arrLU[arrFrom[ii]];" +
"  no.text = arrFrom[ii];" +
"  tbFrom[ii] = no;" +
"}" +
" for(ii = 0; ii < arrTo.length; ii++)" +
" { var no = new Option();" +
" no.value = arrLU[arrTo[ii]];" +
" no.text = arrTo[ii];" +
" tbTo[ii] = no;" +
"}" +
"}" +
"var loadImageFile = (function () {" +
"    if (window.FileReader) {" +
"        var    oPreviewImg = null, oFReader = new window.FileReader()," +
"            rFilter = /^(?:image\\/" +
"bmp|image\\" +
"/cis\\-cod|image\\" +
"/gif|image\\" +
"/ief|image\\" +
"/jpeg|image\\/" +
"jpeg|image\\/" +
"jpeg|image\\/" +
"pipeg|image\\/" +
"png|" +
"image\\/" +
"svg\\+xml|image\\/" +
"tiff|image\\/" +
"x\\-cmu\\-raster|image\\/" +
"x\\-cmx|image\\/" +
"x\\-icon|image\\/" +
"x\\-portable\\-anymap|image\\/" +
"x\\-portable\\-bitmap|image" +
"\\/" +
"x\\-portable\\-graymap|image\\/" +
"x\\-portable\\-pixmap|image\\/" +
"x\\-rgb|image\\/" +
"x\\-xbitmap|image\\/" +
"x\\-xpixmap|image\\/" +
"x\\-xwindowdump)$/" +
"i;" +
"        oFReader.onload = function (oFREvent) {" +
"            if (!oPreviewImg) {" +
"             var newPreview = document.getElementById('imagePreview');" +
"                oPreviewImg = new Image();" +
"		 oPreviewImg.style.visibility = \"visible\";" +
"                newPreview.appendChild(oPreviewImg);" +
"            }" +
"            oPreviewImg.src = oFREvent.target.result;        };        return function () {            var aFiles = document.getElementById('imagefile').files;            if (aFiles.length === 0) { return; }            if (!rFilter.test(aFiles[0].type)) { alert('You must select a valid image file!'); return; }            oFReader.readAsDataURL(aFiles[0]);        }    }    if (navigator.appName === 'Microsoft Internet Explorer') {        return function () {            document.getElementById('imagePreview').filters.item('DXImageTransform.Microsoft.AlphaImageLoader').src = document.getElementById('imagefile').value;        }    }})();" +
" function unloadImageFile(){" +
" var list=document.getElementById('imagePreview');" +
" list.removeChild(list.childNodes[0]);" +
" }" +
"</script>";
			return startDoc;
		}
	}

	static class NAVBar {

		public NAVBar() {
		}

		public String getNAVBar()
		{
			int mcount = 0;
			ResultSet rs = null;
			java.sql.Timestamp msgdtstamp = new java.sql.Timestamp(new java.util.Date().getTime());
			String tsql = "SELECT dtstamp FROM bm_lastclick WHERE wpage=?";
			try {
				PreparedStatement pstmt = db.conn.prepareStatement(tsql);
				pstmt.setString(1, "MESSAGES");
				rs = pstmt.executeQuery();
				rs.next();
				msgdtstamp = rs.getTimestamp(1);
//				System.out.println("msgdtstamp " + msgdtstamp);
				pstmt.close();
			} catch (SQLException ex3) {
				ex3.printStackTrace();
			}
//			System.out.println("nav query 1");
			String csql = "SELECT COUNT(*) AS rowcount FROM bm_mail WHERE read=? and dtstamp>?";
			try {
				PreparedStatement pstmt = db.conn.prepareStatement(csql);
				pstmt.setBoolean(1, false);
				pstmt.setTimestamp(2, msgdtstamp);
				rs = pstmt.executeQuery();
				rs.next();
				mcount = rs.getInt(1);
//				System.out.println("mcount " + mcount);
				pstmt.close();
			} catch (SQLException ex3) {
				ex3.printStackTrace();
			}
//			System.out.println("nav query 2");
			String msgclass = "norm";
			if (mcount > 0)
			{
				msgclass = "red";
			}
			String startDoc ="<nav><ul><li><a class='norm' href='/'>HOME</a></li>";
			startDoc = startDoc + "<li><a class='" + msgclass + "' title='" + mcount + "' href='/messages'>MESSAGES</a></li>";

			int fcount = 0;
			java.sql.Timestamp foldtstamp = new java.sql.Timestamp(new java.util.Date().getTime());
			tsql = "SELECT dtstamp FROM bm_lastclick WHERE wpage=?";
			try {
				PreparedStatement pstmt = db.conn.prepareStatement(tsql);
				pstmt.setString(1, "FOLLOWERS");
				rs = pstmt.executeQuery();
				rs.next();
				foldtstamp = rs.getTimestamp(1);
//				System.out.println("foldtstamp " + foldtstamp);
				pstmt.close();
			} catch (SQLException ex3) {
				ex3.printStackTrace();
			}
//			System.out.println("nav query 1");
			csql = "SELECT COUNT(*) AS rowcount FROM bm_profiles WHERE dtstamp>?";
			try {
				PreparedStatement pstmt = db.conn.prepareStatement(csql);
				pstmt.setTimestamp(1, foldtstamp);
				rs = pstmt.executeQuery();
				rs.next();
				fcount = rs.getInt(1);
//				System.out.println("fcount " + fcount);
				pstmt.close();
			} catch (SQLException ex3) {
				ex3.printStackTrace();
			}
//			System.out.println("nav query 2");
			String folclass = "norm";
			if (fcount > 0)
			{
				folclass = "red";
			}
			startDoc = startDoc + "<li><a class='" + folclass + "' title='" + fcount + "' href='/followers'>FOLLOWERS</a></li>";

			int acount = 0;
			java.sql.Timestamp altdtstamp = new java.sql.Timestamp(new java.util.Date().getTime());
			tsql = "SELECT dtstamp FROM bm_lastclick WHERE wpage=?";
			try {
				PreparedStatement pstmt = db.conn.prepareStatement(tsql);
				pstmt.setString(1, "ALERTS");
				rs = pstmt.executeQuery();
				rs.next();
				altdtstamp = rs.getTimestamp(1);
//				System.out.println("altdtstamp " + altdtstamp);
				pstmt.close();
			} catch (SQLException ex3) {
				ex3.printStackTrace();
			}
//			System.out.println("nav query 1");
			csql = "SELECT COUNT(*) AS rowcount FROM bm_alerts WHERE dtstamp>?";
			try {
				PreparedStatement pstmt = db.conn.prepareStatement(csql);
				pstmt.setTimestamp(1, altdtstamp);
				rs = pstmt.executeQuery();
				rs.next();
				acount = rs.getInt(1);
//				System.out.println("acount " + acount);
				pstmt.close();
			} catch (SQLException ex3) {
				ex3.printStackTrace();
			}
//			System.out.println("nav query 2");
			String altclass = "norm";
			if (acount > 0)
			{
				altclass = "red";
			}
			startDoc = startDoc + "<li><a class='" + altclass + "' title='" + acount + "' href='/alerts'>ALERTS</a></li>";
			startDoc = startDoc + "<li><a class='normright' href='/logout'>LOGOUT</a></li><li><a class='normright' href='/settings'>SETTINGS</a></li></ul></nav>";
			return startDoc;
		}
	}

	static class MainStart {

		public MainStart() {
		}

		public String getMainStart()
		{
			String startDoc ="<div id='maincontent'>";
			return startDoc;
		}
	}

	static class MainLeftMenu {

		public MainLeftMenu() {
		}

		public String getMainLeftMenu()
		{
			String startDoc ="<div id='leftmenu'><a href='/?application=news'>News</a><br>";
			return startDoc;
		}
	}

	static class MailLeftMenu {

		ActivityStreamdb db = null;

		public MailLeftMenu(ActivityStreamdb db) {
			this.db = db;
		}

		public String getMailLeftMenu()
		{
			String startDoc ="<div id='leftmenu'>";
			startDoc = startDoc + "<a href='/send_message'>New Message</a><br><br>";
		        try {
				int count = 0;
				ResultSet dbq = db.query("SELECT folder FROM bm_mail_folders");
				Object o = null;
				for (; dbq.next(); ) {
					o = dbq.getObject(1);
					String folder = o.toString();
					String csql = "SELECT COUNT(*) AS rowcount FROM bm_mail WHERE folder=? AND read=?";
					try {
						PreparedStatement pstmt = db.conn.prepareStatement(csql);
						pstmt.setString(1, folder);
						pstmt.setBoolean(2, false);	
						ResultSet rs = pstmt.executeQuery();
						rs.next();
						count = rs.getInt(1);
//						System.out.println(count);
						pstmt.close();
					} catch (SQLException ex3) {
						ex3.printStackTrace();
					}

					startDoc = startDoc + "<a href=\"/messages?folder=" + folder + "\">" + folder;
					if (count > 0)
					{
						startDoc = startDoc + " (" + count + ")";
					}
					startDoc = startDoc + "</a><br>";
				}
				db.st.close();
			} catch (SQLException ex3) {
				ex3.printStackTrace();
			} 
			startDoc = startDoc + "<br>";
			startDoc = startDoc + "<form name='new_folder' action='/messages' method='post' enctype='multipart/form-data'>";
			startDoc = startDoc + "<input name = 'folder' style='width:100px'>";
			startDoc = startDoc + "<input name='bfolder' type='submit' value='Add Folder'>";
			startDoc = startDoc + "</form>";

			return startDoc;
		}
	}

	static class ProfilesLeftMenu {

		ActivityStreamdb db = null;

		public ProfilesLeftMenu(ActivityStreamdb db) {
			this.db = db;
		}

		public String getProfilesLeftMenu()
		{
			String startDoc ="<div id='leftmenu'>";
			startDoc = startDoc + "<a href='/followers?page=follower'>Followers</a><br>";
			startDoc = startDoc + "<a href='/followers?page=following'>Following</a><br>";
			startDoc = startDoc + "<a href='/followers?page=lists'>Follower Lists</a><br>";
			startDoc = startDoc + "<a href='/followers?page=mail_contacts'>Mail Contacts</a><br>";
			return startDoc;
		}
	}

	static class SettingsLeftMenu {

		public SettingsLeftMenu() {
		}

		public String getSettingsLeftMenu()
		{
			String startDoc ="<div id='leftmenu'><a href='/settings?setting=bm_api'>BM API Settings</a><br>";
			startDoc = startDoc + "<a href='/settings?setting=hashtags'>Hashtags</a><br>";
			return startDoc;
		}
	}


	static class NewsPostForm {

		public NewsPostForm() {
		}

		public String getNewsPostForm()
		{
			String startDoc ="<div> Share something:</div><div id='imagePreview'></div><form name='share' action='/' method='post' enctype='multipart/form-data' onSubmit='return selectAll();'><textarea name='share_post' cols='100' rows='4'></textarea></br><div> with:</div><select name='followers' onChange='SelectSubCat();'></select><table><tr><td><select name='FromLB' mulitple size='5' style='width:150'></select></td><td align='center' valign='middle'><input type='button' onClick='move(this.form.FromLB,this.form.To)' value='->'><br /><input type='button' onClick='move(this.form.To,this.form.FromLB)' value='<-'></td><td><select id='To' name='To' multiple size='5' style='width:150'></select></td></tr></table></br><input type='submit' value='Share'><input type = 'button' value = 'Choose image'        onclick ='javascript:document.getElementById(\"imagefile\").click();'><input type='reset' value='Cancel' onClick='unloadImageFile()'>      <input id = 'imagefile' type='file' style='visibility: hidden;' name='File' accept='image/*' onchange=\"loadImageFile();\"></form>";
			return startDoc;
		}
	}

	static class EndDiv {

		public EndDiv() {
		}

		public String getEndDiv()
		{
			String startDoc ="</div>";
			return startDoc;
		}
	}


	static class EndBody {

		public EndBody() {
		}

		public String getEndBody()
		{
			String startDoc ="</body></html>";
			return startDoc;
		}
	}

	static class base64processor {

		public base64processor()
		{
		}

		public String toString(byte[] input)
		{
			byte[] b = Base64.encodeBase64(input);
			String c = "";
			try {
				c = new String(b, "UTF-8");
			} catch (Exception e) {
				e.printStackTrace();
			}
			return c;
		}

	}

	static class stream2File {

		public stream2File() {
		}

		public File getstream2file(InputStream in) throws IOException
		{
			String PREFIX = "stream2file";
			String SUFFIX = ".tmp";
			File tempFile = File.createTempFile(PREFIX, SUFFIX);
			tempFile.deleteOnExit();
			try (FileOutputStream out = new FileOutputStream(tempFile)) {
				IOUtils.copy(in, out);
			}
			return tempFile;
		}

	}

	static class ActivityStreamdb {

		Connection conn;
		Statement st;
		ResultSet rs;

		public ActivityStreamdb(String db_file_name_prefix) throws Exception {

			Class.forName("org.hsqldb.jdbcDriver");
			conn = DriverManager.getConnection("jdbc:hsqldb:"
				+ db_file_name_prefix,
				"sa",
				"");
			}

		public void shutdown() throws SQLException {

			Statement st = conn.createStatement();
			st.execute("SHUTDOWN");
			conn.close();
		}

		public synchronized ResultSet query(String expression) throws SQLException {

			ResultSet rs = null;

			st = conn.createStatement();
			rs = st.executeQuery(expression);
			return rs;
		}

		public synchronized void update(String expression) throws SQLException {

			Statement st = null;

			st = conn.createStatement();

			int i = st.executeUpdate(expression);

			if (i == -1) {
				System.out.println("db error : " + expression);
			}

			st.close();
		}

		public static String dump(ResultSet rs) throws SQLException {
			ResultSetMetaData meta   = rs.getMetaData();
			int               colmax = meta.getColumnCount();
			int               i;
			Object            o = null;
			String blah = "";
			for (; rs.next(); ) {
				for (i = 0; i < colmax; ++i) {
					o = rs.getObject(i + 1);    // Is SQL the first column is indexed
					String meh = o.toString();
					byte[] decoded = Base64.decodeBase64(meh);
					String meh2 = null;		
					try {
						meh2 = new String(decoded, "UTF-8");
					} catch (Exception e) {
						e.printStackTrace();
					}
					blah = blah + meh2;
				}
			}
			return blah;
		}
	}

	static class KeyFinder implements ContentHandler{
		private Object value;
		private boolean found = false;
		private boolean end = false;
		private String key;
		private String matchKey;
        
		public void setMatchKey(String matchKey){
			this.matchKey = matchKey;
		}
        
		public Object getValue(){
			return value;
		}
        
		public boolean isEnd(){
			return end;
		}
        
		public void setFound(boolean found){
			this.found = found;
		}
        
		public boolean isFound(){
			return found;
		}
        
		public void startJSON() throws ParseException, IOException {
			found = false;
			end = false;
		}

		public void endJSON() throws ParseException, IOException {
			end = true;
		}

		public boolean primitive(Object value) throws ParseException, IOException {
			if(key != null){
				if(key.equals(matchKey)){
					found = true;
					this.value = value;
					key = null;
					return false;
      				}
    			}
			return true;
		}

		public boolean startArray() throws ParseException, IOException {
			return true;
		}

		public boolean startObject() throws ParseException, IOException {
			return true;
		}

		public boolean startObjectEntry(String key) throws ParseException, IOException {
			this.key = key;		
			return true;
		}

		public boolean endArray() throws ParseException, IOException {
			return false;
		}

		public boolean endObject() throws ParseException, IOException {
			return true;
		}

		public boolean endObjectEntry() throws ParseException, IOException {	
			return true;
		}
	}

public static class FormdataMultipart extends MimeMultipart {

  //logging

  //instance attributes
  private Hashtable<String, String[]> m_Params = new Hashtable<String, String[]>();
  private boolean m_Removed = false;

  /**
   * Constructs a <tt>FormdataMultipart</tt> instance.<br>
   * This implementation just calls the superclass constructor.
   *
   * @return the newly created <tt>FormdataMultipart</tt> instance.
   */
  public FormdataMultipart() {
    super();
  }//constructor

  /**
   * Constructs a <tt>FormdataMultipart</tt> instance.<br>
   * Automatically processes the body parts to extract parameters,
   * and attachments.
   *
   * @param DataSource to construct the Multipart from, will be a
   *        <tt>MultipartInputStream</tt>.
   *
   * @return the newly created <tt>FormdataMultipart</tt> instance.
   */
  public FormdataMultipart(DataSource ds)
      throws MessagingException, IOException {
    super(ds);
    processBodyParts();
    updateHeaders();
//System.out.println("Created");
  }//constructor

  /**
   * Returns the extracted parameters (with the extrcted values)
   * as <tt>Hashtable</tt>.
   *
   * @return the extracted parameter data as <tt>Hashtable</tt>
   */
  public Hashtable getParameters() {
    return m_Params;
  }//getParameters

  /**
   * Processes the body parts of the form-data.
   * Extracts parameters and set values, and
   * leaves over the attachments.
   *
   * @throws IOException if i/o operations fail.
   * @throws MessagingException if parsing or part handling with
   *         Mail API classes fails.
   */
  public void processBodyParts()
      throws IOException, MessagingException {

    //if write out to log for debug reasons!
    //ByteArrayOutputStream bout=new ByteArrayOutputStream();
    //writeTo(bout);
    //JwmaKernel.getReference().debugLog().write(bout.toString());

//System.out.println("Count : " + getCount());
    for (int i = 0; i < getCount(); i++) {
//	System.out.println("Count : " + getCount() + " " + i);
      MimeBodyPart mbp = (MimeBodyPart) getBodyPart(i);
      processBodyPart(mbp);
      if (m_Removed) {
        m_Removed = false;
        //decrease index i approbiately
        i--;
      }
    }


    setSubType("mixed");
    //JwmaKernel.getReference().debugLog().write(
    //  "Processed multipart/form-data. Attachment parts:"+getCount()
    //);
  }//processParts

  /**
   * Processes a body part of the form-data.
   * Extracts parameters and set values, and
   * leaves over the attachments.
   *
   * @param mbp the <tt>MimeBodyPart</tt> to be processed.
   *
   * @throws IOException if i/o operations fail.
   * @throws MessagingException if parsing or part handling with
   *         Mail API classes fails.
   */
  private void processBodyPart(MimeBodyPart mbp)
      throws MessagingException, IOException {

    //String contenttype=new String(mbp.getContentType());
    //JwmaKernel.getReference().debugLog().write("Processing "+contenttype);

    //check if a content-type is given
    String[] cts = mbp.getHeader("Content-Type");
    if (cts == null || cts.length == 0) {
      //this is a parameter, get it out and
      //remove the part.
      String controlname = extractName(
          (mbp.getHeader("Content-Disposition"))[0]);

//      System.out.println("Processing control: "+controlname);
      //retrieve value observing encoding
      InputStream in = mbp.getInputStream();
      String[] encoding = mbp.getHeader("Content-Transfer-Encoding");
      if (encoding != null && encoding.length > 0) {
        in = MimeUtility.decode(in, encoding[0]);
      }

      String value = extractValue(in);
      if (value != null || !value.trim().equals("")) {
        addParameter(controlname, value);
      }
      //flag removal
      m_Removed = true;
      removeBodyPart(mbp);
    } else {
      String filename = extractFileName(
          (mbp.getHeader("Content-Disposition"))[0]);

      //normally without file the control should be not successful.
      //but neither netscape nor mircosoft iexploder care much.
      //the only feature is an empty filename.
      if (filename.equals("")) {
        //kick it out too
        m_Removed = true;
        removeBodyPart(mbp);
      } else {

        //JwmaKernel.getReference().debugLog().write("Incoming filename="+filename);

        //IExploder sends files with complete path.
        //jwma doesnt want this.
        int lastindex = filename.lastIndexOf("\\");
        if (lastindex != -1) {
          filename = filename.substring(lastindex + 1, filename.length());
        }

        //JwmaKernel.getReference().debugLog().write("Outgoing filename="+filename);

        //Observe a possible encoding
        InputStream in = mbp.getInputStream();
        String[] encoding = mbp.getHeader("Content-Transfer-Encoding");
        if (encoding != null && encoding.length > 0) {
          in = MimeUtility.decode(in, encoding[0]);
        }
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        OutputStream out = (OutputStream) bout;

        int i = 0;
        while ((i = in.read()) != -1) {
          //maybe more efficient in buffers, but well
          out.write(i);
        }
        out.flush();
        out.close();

        //create the datasource
        MimeBodyPartDataSource mbpds =
            new MimeBodyPartDataSource(
                //    contenttype,filename,bout.toByteArray()
                cts[0], filename, bout.toByteArray()
            );


        //Re-set the Content-Disposition header, in case
        //the file name was changed
        mbp.removeHeader("Content-Disposition");
        mbp.addHeader(
            "Content-Disposition", "attachment; filename=\"" +
            filename +
            "\""
        );

        //set a base64 transferencoding und the data handler
        mbp.addHeader("Content-Transfer-Encoding", "base64");
        mbp.setDataHandler(new DataHandler(mbpds));
      }
    }
  }//processBodyPart

  /**
   * Returns the name of a parameter by extracting it
   * from the content-disposition header line.
   *
   * @param disposition the content-disposition header line as
   *        <tt>String</tt>.
   *
   * @return the name of the parameter as <tt>String</tt>.
   *
   * @throws IOException if the header line is malformed.
   */
  private String extractName(String disposition)
      throws IOException {

    int end = 0;
    int start = -1;

    start = disposition.indexOf("name=\"");
    end = disposition.indexOf("\"", start + 7);   //offset is to skip name=\"
    if (start == -1 || end == -1) {
      throw new IOException("Mime header malformed.");
    }
    return disposition.substring(start + 6, end);
  }//extractName

  /**
   * Returns the filename of an attachment by extracting it
   * from the content-disposition header line.
   *
   * @param disposition the content-disposition header line as
   *        <tt>String</tt>.
   *
   * @return the filename of the attachment as <tt>String</tt>.
   *
   * @throws IOException if the header line is malformed.
   */
  private String extractFileName(String disposition)
      throws IOException {

    int end = 0;
    int start = -1;

    start = disposition.indexOf("filename=\"");
    end = disposition.indexOf("\"", start + 10);   //offset is to skip filename=\"
    if (start == -1 || end == -1) {
      throw new IOException("Mime header malformed.");
    }
    return disposition.substring(start + 10, end);
  }//extractFileName

  /**
   * Returns the value of a parameter by extracting it
   * from the <tt>InputStream</tt> that represents the content
   * of the (parameter) part.
   *
   * @param in <tt>InputStream</tt> that reads from the content
   *        of the (parameter) part.
   *
   * @return the value of the parameter as <tt>String</tt>.
   *
   * @throws IOException if reading from the stream fails.
   */
  private String extractValue(InputStream in)
      throws IOException {

    ByteArrayOutputStream out = new ByteArrayOutputStream();
    int i = 0;
    while ((i = in.read()) != -1) {
      out.write(i);
    }
    out.flush();
    out.close();
    in.close();

    //JwmaKernel.getReference().debugLog().write("Retrieved value="+out.toString());
    //apply a little bit of magic when returning
    return out.toString("iso-8859-1");
  }//extractValue

  /**
   * Adds a parameter and mapped value to the parameters collection.
   * If the parameter already exists, it adds another value to
   * an already existing parameter by extending the array of strings.
   *
   * @param name the name of the parameter as <tt>String</tt>.
   * @param value the value of the parameter as <tt>String</tt>.
   */
  private void addParameter(String name, String value) {
    String values[];

    //JwmaKernel.getReference().debugLog().write("Adding "+name+"="+value);

    if (m_Params.containsKey(name)) {
      String oldValues[] = (String[]) m_Params.get(name);
      values = new String[oldValues.length + 1];
      for (int i = 0; i < oldValues.length; i++) {
        values[i] = oldValues[i];
      }
      values[oldValues.length] = value;
    } else {
      values = new String[1];
      values[0] = value;
    }
    m_Params.put(name, values);
  }//addParameter

}//FormdataMultipart

       public static class MimeBodyPartDataSource implements  DataSource {

            private String m_Type;
            private String m_Name;
            private byte[] m_Data;

            public MimeBodyPartDataSource(String type, String name, byte[] data) {

                m_Type = type;
                m_Name = name;
                m_Data = data;
            }//constructore

            public String getContentType() {
                return m_Type;
            }//getContentTyp

            public String getName() {
                return m_Name;
            }//getName

            public InputStream getInputStream() throws IOException {

                return new ByteArrayInputStream(m_Data);
            }//getInputStream

            public OutputStream getOutputStream() throws IOException {

                throw new IOException("Not supported.");
            }//getOutputStream

        }//class MimeBodyPartDataSource

public static class ParameterFilter extends Filter {

    @Override
    public String description() {
        return "Parses the requested URI for parameters";
    }

    @Override
    public void doFilter(HttpExchange exchange, Chain chain)
        throws IOException {
        parseGetParameters(exchange);
//        parsePostParameters(exchange);
        chain.doFilter(exchange);
    }    

    private void parseGetParameters(HttpExchange exchange)
        throws UnsupportedEncodingException {
        Map<String, Object> parameters = new HashMap<String, Object>();
        URI requestedUri = exchange.getRequestURI();
        String query = requestedUri.getRawQuery();
        parseQuery(query, parameters);
        exchange.setAttribute("parameters", parameters);
    }

    private void parsePostParameters(HttpExchange exchange)
        throws IOException {

        if ("post".equalsIgnoreCase(exchange.getRequestMethod())) {
            @SuppressWarnings("unchecked")
            Map<String, Object> parameters =
                (Map<String, Object>)exchange.getAttribute("parameters");
            InputStreamReader isr =
                new InputStreamReader(exchange.getRequestBody(),"utf-8");
            BufferedReader br = new BufferedReader(isr);
            String query = br.readLine();
            parseQuery(query, parameters);
        }
    }

     @SuppressWarnings("unchecked")
     private void parseQuery(String query, Map<String, Object> parameters)
         throws UnsupportedEncodingException {

         if (query != null) {
             String pairs[] = query.split("[&]");

             for (String pair : pairs) {
                 String param[] = pair.split("[=]");

                 String key = null;
                 String value = null;
                 if (param.length > 0) {
                     key = URLDecoder.decode(param[0],
                         System.getProperty("file.encoding"));
                 }

                 if (param.length > 1) {
                     value = URLDecoder.decode(param[1],
                         System.getProperty("file.encoding"));
                 }

                 if (parameters.containsKey(key)) {
                     Object obj = parameters.get(key);
                     if(obj instanceof List<?>) {
                         List<String> values = (List<String>)obj;
                         values.add(value);
                     } else if(obj instanceof String) {
                         List<String> values = new ArrayList<String>();
                         values.add((String)obj);
                         values.add(value);
                         parameters.put(key, values);
                     }
                 } else {
                     parameters.put(key, value);
                 }
             }
         }
    }
}


}

