text:
package org.sakaiproject.announcement.impl;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Vector;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Stack;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sakaiproject.alias.api.Alias;
import org.sakaiproject.alias.api.AliasService;
import org.sakaiproject.announcement.api.AnnouncementChannel;
import org.sakaiproject.announcement.api.AnnouncementChannelEdit;
import org.sakaiproject.announcement.api.AnnouncementMessage;
import org.sakaiproject.announcement.api.AnnouncementMessageEdit;
import org.sakaiproject.announcement.api.AnnouncementMessageHeader;
import org.sakaiproject.announcement.api.AnnouncementMessageHeaderEdit;
import org.sakaiproject.announcement.api.AnnouncementService;
import org.sakaiproject.authz.api.FunctionManager;
import org.sakaiproject.content.api.ContentHostingService;
import org.sakaiproject.content.api.ContentResource;
import org.sakaiproject.entity.api.ContextObserver;
import org.sakaiproject.entity.api.Edit;
import org.sakaiproject.entity.api.Entity;
import org.sakaiproject.entity.api.EntityNotDefinedException;
import org.sakaiproject.entity.api.EntityPermissionException;
import org.sakaiproject.entity.api.EntityPropertyNotDefinedException;
import org.sakaiproject.entity.api.EntityPropertyTypeException;
import org.sakaiproject.entity.api.EntityTransferrer;
import org.sakaiproject.entity.api.EntityTransferrerRefMigrator;
import org.sakaiproject.entity.api.HttpAccess;
import org.sakaiproject.entity.api.Reference;
import org.sakaiproject.entity.api.ResourceProperties;
import org.sakaiproject.entity.api.ResourcePropertiesEdit;
import org.sakaiproject.event.api.NotificationEdit;
import org.sakaiproject.event.api.NotificationService;
import org.sakaiproject.exception.IdInvalidException;
import org.sakaiproject.exception.IdUnusedException;
import org.sakaiproject.exception.IdUsedException;
import org.sakaiproject.exception.InUseException;
import org.sakaiproject.exception.PermissionException;
import org.sakaiproject.javax.Filter;
import org.sakaiproject.message.api.Message;
import org.sakaiproject.message.api.MessageChannel;
import org.sakaiproject.message.api.MessageEdit;
import org.sakaiproject.message.api.MessageHeader;
import org.sakaiproject.message.api.MessageHeaderEdit;
import org.sakaiproject.message.util.BaseMessage;
import org.sakaiproject.site.api.Site;
import org.sakaiproject.site.api.SiteService;
import org.sakaiproject.site.api.ToolConfiguration;
import org.sakaiproject.time.api.Time;
import org.sakaiproject.tool.api.ToolManager;
import org.sakaiproject.util.MergedList;
import org.sakaiproject.util.ResourceLoader;
import org.sakaiproject.util.StringUtil;
import org.sakaiproject.util.Validator;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * <p>
 * BaseAnnouncementService extends the BaseMessage for the specifics of Announcement.
 * </p>
 */

public abstract class BaseAnnouncementService extends BaseMessage implements AnnouncementService, ContextObserver,
		EntityTransferrer, EntityTransferrerRefMigrator
{
	/** Our logger. */
	private static Logger M_log = LoggerFactory.getLogger(BaseAnnouncementService.class);

	/** private constants definitions */
	private final static String SAKAI_ANNOUNCEMENT_TOOL_ID = "sakai.announcements";
	private static final String PORTLET_CONFIG_PARM_MERGED_CHANNELS = "mergedAnnouncementChannels";

	/** Messages, for the http access. */
	protected static ResourceLoader rb = new ResourceLoader("annc-access");

	// XML DocumentBuilder and Transformer for RSS Feed
	private DocumentBuilder docBuilder = null;
	private Transformer docTransformer = null;

	private ContentHostingService contentHostingService;
	private SiteEmailNotificationAnnc siteEmailNotificationAnnc;

	/**
	 * Dependency: contentHostingService.
	 *
	 * @param service
	 *        The NotificationService.
	 */
	public void setContentHostingService(ContentHostingService service)
	{
		contentHostingService = service;
	}

	public void setSiteEmailNotificationAnnc(SiteEmailNotificationAnnc siteEmailNotificationAnnc) {
		this.siteEmailNotificationAnnc = siteEmailNotificationAnnc;
	}

	private FunctionManager functionManager;
	public void setFunctionManager(FunctionManager functionManager) {
		this.functionManager = functionManager;
	}

	private AliasService aliasService;
	public void setAliasService(AliasService aliasService) {
		this.aliasService = aliasService;
	}

	private ToolManager toolManager;
	public void setToolManager(ToolManager toolManager) {
		this.toolManager = toolManager;

	}
	/**********************************************************************************************************************************************************************************************************************************************************
	 * Constructors, Dependencies and their setter methods
	 *********************************************************************************************************************************************************************************************************************************************************/

	/** Dependency: NotificationService. */
	protected NotificationService m_notificationService = null;

	/**
	 * Dependency: NotificationService.
	 *
	 * @param service
	 *        The NotificationService.
	 */
	public void setNotificationService(NotificationService service)
	{
		m_notificationService = service;
	}

	/**********************************************************************************************************************************************************************************************************************************************************
	 * Init and Destroy
	 *********************************************************************************************************************************************************************************************************************************************************/

	/**
	 * Final initialization, once all dependencies are set.
	 */
	public void init()
	{
		try
		{
			super.init();

			// register a transient notification for announcements
			NotificationEdit edit = m_notificationService.addTransientNotification();

			// set functions
			edit.setFunction(eventId(SECURE_ADD));
			edit.addFunction(eventId(SECURE_UPDATE_OWN));
			edit.addFunction(eventId(SECURE_UPDATE_ANY));

			// set the filter to any announcement resource (see messageReference())
			edit.setResourceFilter(getAccessPoint(true) + Entity.SEPARATOR + REF_TYPE_MESSAGE);

			// set the action
			edit.setAction(siteEmailNotificationAnnc);

			// register functions
			functionManager.registerFunction(eventId(SECURE_READ));
			functionManager.registerFunction(eventId(SECURE_ADD));
			functionManager.registerFunction(eventId(SECURE_REMOVE_ANY));
			functionManager.registerFunction(eventId(SECURE_REMOVE_OWN));
			functionManager.registerFunction(eventId(SECURE_UPDATE_ANY));
			functionManager.registerFunction(eventId(SECURE_UPDATE_OWN));
			functionManager.registerFunction(eventId(SECURE_ALL_GROUPS));

			// Sakai v2.4: UI end says hidden, 'under the covers' says draft
			// Done so import from old sites causes drafts to 'become' hidden in new sites
			functionManager.registerFunction(eventId(SECURE_READ_DRAFT));

			// entity producer registration
			m_entityManager.registerEntityProducer(this, REFERENCE_ROOT);

			// create DocumentBuilder for RSS Feed
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			factory.setIgnoringComments(true);  // ignore comments
			factory.setNamespaceAware(true);		// namespace aware should be true
			factory.setValidating(false);		   // we're not validating
			docBuilder = factory.newDocumentBuilder();

			TransformerFactory tFactory = TransformerFactory.newInstance();
			docTransformer = tFactory.newTransformer();

			M_log.info("init()");
		}
		catch (Throwable t)
		{
			M_log.warn("init(): ", t);
		}

	} // init

	/**********************************************************************************************************************************************************************************************************************************************************
	 * StorageUser implementation
	 *********************************************************************************************************************************************************************************************************************************************************/

	/**
	 * Construct a new continer given just ids.
	 *
	 * @param ref
	 *        The container reference.
	 * @return The new containe Resource.
	 */
	public Entity newContainer(String ref)
	{
		return new BaseAnnouncementChannelEdit(ref);
	}

	/**
	 * Construct a new container resource, from an XML element.
	 *
	 * @param element
	 *        The XML.
	 * @return The new container resource.
	 */
	public Entity newContainer(Element element)
	{
		return new BaseAnnouncementChannelEdit(element);
	}

	/**
	 * Construct a new container resource, as a copy of another
	 *
	 * @param other
	 *        The other contianer to copy.
	 * @return The new container resource.
	 */
	public Entity newContainer(Entity other)
	{
		return new BaseAnnouncementChannelEdit((MessageChannel) other);
	}

	/**
	 * Construct a new rsource given just an id.
	 *
	 * @param container
	 *        The Resource that is the container for the new resource (may be null).
	 * @param id
	 *        The id for the new object.
	 * @param others
	 *        (options) array of objects to load into the Resource's fields.
	 * @return The new resource.
	 */
	public Entity newResource(Entity container, String id, Object[] others)
	{
		return new BaseAnnouncementMessageEdit((MessageChannel) container, id);
	}

	/**
	 * Construct a new resource, from an XML element.
	 *
	 * @param container
	 *        The Resource that is the container for the new resource (may be null).
	 * @param element
	 *        The XML.
	 * @return The new resource from the XML.
	 */
	public Entity newResource(Entity container, Element element)
	{
		return new BaseAnnouncementMessageEdit((MessageChannel) container, element);
	}

	/**
	 * Construct a new resource from another resource of the same type.
	 *
	 * @param container
	 *        The Resource that is the container for the new resource (may be null).
	 * @param other
	 *        The other resource.
	 * @return The new resource as a copy of the other.
	 */
	public Entity newResource(Entity container, Entity other)
	{
		return new BaseAnnouncementMessageEdit((MessageChannel) container, (Message) other);
	}

	/**
	 * Construct a new continer given just ids.
	 *
	 * @param ref
	 *        The container reference.
	 * @return The new containe Resource.
	 */
	public Edit newContainerEdit(String ref)
	{
		BaseAnnouncementChannelEdit rv = new BaseAnnouncementChannelEdit(ref);
		rv.activate();
		return rv;
	}

	/**
	 * Construct a new container resource, from an XML element.
	 *
	 * @param element
	 *        The XML.
	 * @return The new container resource.
	 */
	public Edit newContainerEdit(Element element)
	{
		BaseAnnouncementChannelEdit rv = new BaseAnnouncementChannelEdit(element);
		rv.activate();
		return rv;
	}

	/**
	 * Construct a new container resource, as a copy of another
	 *
	 * @param other
	 *        The other contianer to copy.
	 * @return The new container resource.
	 */
	public Edit newContainerEdit(Entity other)
	{
		BaseAnnouncementChannelEdit rv = new BaseAnnouncementChannelEdit((MessageChannel) other);
		rv.activate();
		return rv;
	}

	/**
	 * Construct a new rsource given just an id.
	 *
	 * @param container
	 *        The Resource that is the container for the new resource (may be null).
	 * @param id
	 *        The id for the new object.
	 * @param others
	 *        (options) array of objects to load into the Resource's fields.
	 * @return The new resource.
	 */
	public Edit newResourceEdit(Entity container, String id, Object[] others)
	{
		BaseAnnouncementMessageEdit rv = new BaseAnnouncementMessageEdit((MessageChannel) container, id);
		rv.activate();
		return rv;
	}

	/**
	 * Construct a new resource, from an XML element.
	 *
	 * @param container
	 *        The Resource that is the container for the new resource (may be null).
	 * @param element
	 *        The XML.
	 * @return The new resource from the XML.
	 */
	public Edit newResourceEdit(Entity container, Element element)
	{
		BaseAnnouncementMessageEdit rv = new BaseAnnouncementMessageEdit((MessageChannel) container, element);
		rv.activate();
		return rv;
	}

	/**
	 * Construct a new resource from another resource of the same type.
	 *
	 * @param container
	 *        The Resource that is the container for the new resource (may be null).
	 * @param other
	 *        The other resource.
	 * @return The new resource as a copy of the other.
	 */
	public Edit newResourceEdit(Entity container, Entity other)
	{
		BaseAnnouncementMessageEdit rv = new BaseAnnouncementMessageEdit((MessageChannel) container, (Message) other);
		rv.activate();
		return rv;
	}

	/**
	 * Collect the fields that need to be stored outside the XML (for the resource).
	 *
	 * @return An array of field values to store in the record outside the XML (for the resource).
	 */
	public Object[] storageFields(Entity r)
	{
		Object[] rv = new Object[5];
		rv[0] = ((Message) r).getHeader().getDate();
		rv[1] = ((Message) r).getHeader().getFrom().getId();
		rv[2] = ((AnnouncementMessage) r).getAnnouncementHeader().getDraft() ? "1" : "0";
		rv[3] = r.getProperties().getProperty(ResourceProperties.PROP_PUBVIEW) == null ? "0" : "1";
		rv[4] = ((Message) r).getHeader().getMessage_order();
		// rv[3] = ((AnnouncementMessage) r).getAnnouncementHeader().getAccess() == MessageHeader.MessageAccess.PUBLIC ? "1" : "0";

		return rv;
	}

	/**
	 * Check if this resource is in draft mode.
	 *
	 * @param r
	 *        The resource.
	 * @return true if the resource is in draft mode, false if not.
	 */
	public boolean isDraft(Entity r)
	{
		return ((AnnouncementMessage) r).getAnnouncementHeader().getDraft();
	}

	/**
	 * Access the resource owner user id.
	 *
	 * @param r
	 *        The resource.
	 * @return The resource owner user id.
	 */
	public String getOwnerId(Entity r)
	{
		return ((Message) r).getHeader().getFrom().getId();
	}

	/**
	 * Access the resource date.
	 *
	 * @param r
	 *        The resource.
	 * @return The resource date.
	 */
	public Time getDate(Entity r)
	{
		return ((Message) r).getHeader().getDate();
	}

	/**
	 * Access the resource Message Order.
	 *
	 * @param r
	 *        The resource.
	 * @return The resource order.
	 */
	public Integer getMessage_order(Entity r)
	{
		return ((Message) r).getHeader().getMessage_order();
	}

	/**********************************************************************************************************************************************************************************************************************************************************
	 * Abstractions, etc. satisfied
	 *********************************************************************************************************************************************************************************************************************************************************/

	/**
	 * Report the Service API name being implemented.
	 */
	protected String serviceName()
	{
		return AnnouncementService.class.getName();
	}

	/**
	 * Construct a new message header from XML in a DOM element.
	 *
	 * @param id
	 *        The message Id.
	 * @return The new message header.
	 */
	protected MessageHeaderEdit newMessageHeader(Message msg, String id)
	{
		return new BaseAnnouncementMessageHeaderEdit(msg, id);

	} // newMessageHeader

	/**
	 * Construct a new message header from XML in a DOM element.
	 *
	 * @param el
	 *        The XML DOM element that has the header information.
	 * @return The new message header.
	 */
	protected MessageHeaderEdit newMessageHeader(Message msg, Element el)
	{
		return new BaseAnnouncementMessageHeaderEdit(msg, el);

	} // newMessageHeader

	/**
	 * Construct a new message header as a copy of another.
	 *
	 * @param other
	 *        The other header to copy.
	 * @return The new message header.
	 */
	protected MessageHeaderEdit newMessageHeader(Message msg, MessageHeader other)
	{
		return new BaseAnnouncementMessageHeaderEdit(msg, other);

	} // newMessageHeader

	/**
	 * Form a tracking event string based on a security function string.
	 *
	 * @param secure The security function string.
	 *     NOTE: if this input is null or blank then event id will default to "annc.INVALID_KEY",
	 *           this is only because throwing an exception here would be very disruptive and returning
	 *           a null or blank for the event id would cause other failures (SAK-23804)
	 * @return The event tracking string.
	 */
	protected String eventId(String secure) {
		// https://jira.sakaiproject.org/browse/SAK-23804
		if (StringUtils.isBlank(secure)) {
		    try {
		        throw new IllegalArgumentException("anouncement eventId() input cannot be null or blank");
		    } catch (Exception e) {
		        secure = "INVALID_KEY";
		        M_log.error("Bad call to BaseAnnouncementService.eventId(String) - input string is blank, generating '"+secure+"' event name and logging trace", e);
		    }
		}
		return SECURE_ANNC_ROOT + secure;

	} // eventId

	/**
	 * Return the reference rooot for use in resource references and urls.
	 *
	 * @return The reference rooot for use in resource references and urls.
	 */
	protected String getReferenceRoot()
	{
		return REFERENCE_ROOT;

	} // getReferenceRoot

	/**
	 * {@inheritDoc}
	 */
	public boolean parseEntityReference(String reference, Reference ref)
	{
		if (reference.startsWith(REFERENCE_ROOT))
		{
			String[] parts = StringUtil.split(reference, Entity.SEPARATOR);

			String id = null;
			String subType = null;
			String context = null;
			String container = null;

			// the first part will be null, then next the service, the third will be: "msg", "channel", "announcement" or "rss"
			if (parts.length > 2)
			{
				subType = parts[2];
				if (REF_TYPE_CHANNEL.equals(subType))
				{
					// next is the context id
					if (parts.length > 3)
					{
						context = parts[3];

						// next is the channel id
						if (parts.length > 4)
						{
							id = parts[4];
						}
					}
				}
				else if (REF_TYPE_MESSAGE.equals(subType))
				{
					// next three parts are context, channel (container) and mesage id
					if (parts.length > 5)
					{
						context = parts[3];
						container = parts[4];
						id = parts[5];
					}
				}
				else if (REF_TYPE_ANNOUNCEMENT_RSS.equals(subType) || REF_TYPE_ANNOUNCEMENT.equals(subType))
				{
					// next is the context id
					if (parts.length > 3)
						context = parts[3];
				}
				else
					M_log.warn("parse(): unknown message subtype: " + subType + " in ref: " + reference);
			}

			// Translate context alias into site id (only for rss) if necessary
			if (REF_TYPE_ANNOUNCEMENT_RSS.equals(subType) &&(context != null) && (context.length() > 0))
			{
				if (!m_siteService.siteExists(context))
				{
					try
					{
						String aliasTarget = aliasService.getTarget(context);
						if (aliasTarget.startsWith(REFERENCE_ROOT)) // only support announcement aliases
						{
							parts = StringUtil.split(aliasTarget, Entity.SEPARATOR);
							if (parts.length > 3)
								context = parts[3];
						}
					}
					catch (Exception e)
					{
						M_log.debug(this+".parseEntityReference(): "+e.toString());
						return false;
					}
				}

				// if context still isn't valid, then no valid alias or site was specified
				if (!m_siteService.siteExists(context))
				{
					M_log.warn(this+".parseEntityReference() no valid site or alias: " + context);
					return false;
				}
			}

			ref.set(APPLICATION_ID, subType, id, container, context);

			return true;
		}

		return false;
	}

	/**
	 * @inheritDoc
	 */
	public Reference getAnnouncementReference(String context)
	{
      StringBuilder refString = new StringBuilder();
		refString.append(getAccessPoint(true));
		refString.append(Entity.SEPARATOR);
		refString.append(REF_TYPE_ANNOUNCEMENT);
		refString.append(Entity.SEPARATOR);
		refString.append(context);

		return  m_entityManager.newReference( refString.toString() );
	}

	/**
	 * @inheritDoc
	 */
	@Override
	public String channelReference(String context, String id)
	{
	    /* SAK-19516: for MOTD and Admin Workspace Announcements, the channel reference
	     * is not calculated based on the context and id, but pulled from SAKAI_TOOL_PROPERTY 'channel'.
	     */
		String channelRef = null;
		try {
			ToolConfiguration tool = m_siteService.getSite(context).getToolForCommonId(SAKAI_ANNOUNCEMENT_TOOL_ID);
			if (tool != null) {
				channelRef = tool.getConfig().getProperty(ANNOUNCEMENT_CHANNEL_PROPERTY, null);
			}
		} catch (IdUnusedException e) {
		    // ignore the error, continue with the default method
		    M_log.debug("Could not find channelRef in channel property, falling back to default method...");
		}

		if (channelRef == null || channelRef.trim().length() == 0) {
			channelRef = super.channelReference(context, id);
		}
		return channelRef;

	} // channelReference

	/**
	 * @inheritDoc
	 */
	public String getRssUrl(Reference ref)
	{
      String alias = null;
      List aliasList =  aliasService.getAliases( ref.getReference() );

      if ( ! aliasList.isEmpty() )
         alias = ((Alias)aliasList.get(0)).getId();

      StringBuilder rssUrlString = new StringBuilder();
		rssUrlString.append( m_serverConfigurationService.getAccessUrl() );
		rssUrlString.append(getAccessPoint(true));
		rssUrlString.append(Entity.SEPARATOR);
		rssUrlString.append(REF_TYPE_ANNOUNCEMENT_RSS);
		rssUrlString.append(Entity.SEPARATOR);

      if ( alias != null)
   		rssUrlString.append(alias);
      else
			rssUrlString.append(ref.getContext());

		return rssUrlString.toString();
	}

	/**
	 * {@inheritDoc}
	 */
	public boolean isMessageViewable(AnnouncementMessage message)
	{
		final ResourceProperties messageProps = message.getProperties();

		final Time now = m_timeService.newTime();
		try
		{
			final Time releaseDate = message.getProperties().getTimeProperty(RELEASE_DATE);

			if (now.before(releaseDate))
			{
				return false;
			}
		}
		catch (Exception e)
		{
			// Just not using/set Release Date
		}

		try
		{
			final Time retractDate = message.getProperties().getTimeProperty(RETRACT_DATE);

			if (now.after(retractDate))
			{
				return false;
			}
		}
		catch (Exception e)
		{
			// Just not using/set Retract Date
		}

		return true;
	}

	/**
	 * {@inheritDoc}
	 */
	public void contextCreated(String context, boolean toolPlacement)
	{
		if (toolPlacement) enableMessageChannel(context);
	}

	/**
	 * {@inheritDoc}
	 */
	public void contextUpdated(String context, boolean toolPlacement)
	{
		if (toolPlacement) enableMessageChannel(context);
	}

	/**
	 * {@inheritDoc}
	 */
	public void contextDeleted(String context, boolean toolPlacement)
	{
		disableMessageChannel(context);
	}

	/**
	 * {@inheritDoc}
	 */
	public String[] myToolIds()
	{
		String[] toolIds = { "sakai.announcements" };
		return toolIds;
	}

	/**
	 ** Generate RSS Item element for specified assignment
	 **/
	protected Element generateItemElement( Document doc, AnnouncementMessage msg, Reference msgRef )
	{
			Element item = doc.createElement("item");

			Element el = doc.createElement("title");
			el.appendChild(doc.createTextNode( msg.getAnnouncementHeader().getSubject() ));
			item.appendChild(el);

			el = doc.createElement("author");
			el.appendChild(doc.createTextNode( msg.getHeader().getFrom().getEmail() ));
			item.appendChild(el);

			el = doc.createElement("link");
			el.appendChild(doc.createTextNode( msgRef.getUrl() ));
			item.appendChild(el);

			el = doc.createElement("description");
			el.appendChild(doc.createTextNode( msg.getBody()) );
			item.appendChild(el);

			el = doc.createElement("pubDate");
			Date date = new Date(msg.getHeader().getDate().getTime());
			String pubDate = new SimpleDateFormat("EEE', 'dd' 'MMM' 'yyyy' 'HH:mm:ss' 'Z", Locale.ENGLISH).format(date);
			el.appendChild(doc.createTextNode(pubDate));
			item.appendChild(el);

			el = doc.createElement("message_order");
			el.appendChild(doc.createTextNode( msg.getHeader().getMessage_order().toString()));
			item.appendChild(el);

			// attachments
			List attachments = msg.getAnnouncementHeader().getAttachments();
			if (attachments.size() > 0)
			{
				for (Iterator iAttachments = attachments.iterator(); iAttachments.hasNext();)
				{
					Reference attachment = (Reference) iAttachments.next();
					el = doc.createElement("enclosure");
					el.setAttribute("url",attachment.getUrl());
					el.setAttribute("type",attachment.getType());
					item.appendChild(el);
				}
			}

			return item;
	}

	/**
	 ** Print all Announcements as RSS Feed
	 **/
	protected void printAnnouncementRss( OutputStream out, Reference rssRef )
	{
		try
		{
			Site site = m_siteService.getSite(rssRef.getContext());
			Document doc = docBuilder.newDocument();

			Element root = doc.createElement("rss");
			root.setAttribute("version","2.0");
			doc.appendChild(root);

			Element channel = doc.createElement("channel");
			root.appendChild(channel);

			// add title
			Element el = doc.createElement("title");
			el.appendChild(doc.createTextNode("Announcements for "+site.getTitle()));
			channel.appendChild(el);

			// add description
			el = doc.createElement("description");
			String desc = (site.getDescription()!=null)?site.getDescription():site.getTitle();
			el.appendChild(doc.createTextNode(desc));
			channel.appendChild(el);

			// add link
			el = doc.createElement("link");
			StringBuilder siteUrl = new StringBuilder( m_serverConfigurationService.getServerUrl() );
			siteUrl.append( m_serverConfigurationService.getString("portalPath") );
			siteUrl.append( site.getReference() );
			el.appendChild(doc.createTextNode(siteUrl.toString()));
			channel.appendChild(el);

			// add lastBuildDate
			el = doc.createElement("lastBuildDate");
			String now = new SimpleDateFormat("EEE', 'dd' 'MMM' 'yyyy' 'HH:mm:ss' 'Z", Locale.ENGLISH).format(new Date());
			el.appendChild(doc.createTextNode( now ));
			channel.appendChild(el);

			// add generator
			el = doc.createElement("generator");
			el.appendChild(doc.createTextNode("Sakai Announcements RSS Generator"));
			channel.appendChild(el);

			// get list of public announcements
			AnnouncementChannel anncChan = (AnnouncementChannel)getChannelPublic( channelReference(rssRef.getContext(), SiteService.MAIN_CONTAINER) );
			if ( anncChan == null )
			{
				M_log.warn(this+".printAnnouncementRss invalid request "+rssRef.getContext());
				return;
			}
			List anncList = anncChan.getMessagesPublic(null,false);

			for ( Iterator it=anncList.iterator(); it.hasNext(); )
			{
				AnnouncementMessage msg = (AnnouncementMessage)it.next();
				if ( isMessageViewable(msg) )
				{
					Reference msgRef = m_entityManager.newReference( msg.getReference() );
					Element item = generateItemElement( doc, msg, msgRef );
					channel.appendChild(item);
				}
			}

			docTransformer.transform( new DOMSource(doc), new StreamResult(out) );
		}
		catch (Exception e)
		{
			M_log.warn(this+"printAnnouncementRss ", e);
		}
	}

	/**
	 ** Print specified Announcement as HTML Page
	 **/
	protected void printAnnouncementHtml( PrintWriter out, Reference ref )
		throws EntityPermissionException, EntityNotDefinedException
	{
		try
		{
			// check security on the message, if not a public message (throws if not permitted)
			if ( ref.getProperties().getProperty(ResourceProperties.PROP_PUBVIEW) == null ||
				  !ref.getProperties().getProperty(ResourceProperties.PROP_PUBVIEW).equals(Boolean.TRUE.toString()) )
			{
				unlock(SECURE_READ, ref.getReference());
			}

			AnnouncementMessage msg = (AnnouncementMessage) ref.getEntity();
			AnnouncementMessageHeader hdr = (AnnouncementMessageHeader) msg.getAnnouncementHeader();

			out.println("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"
							+ "<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en\" xml:lang=\"en\">\n"
							+ "<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n"
							+ "<style type=\"text/css\">body{margin:0px;padding:1em;font-family:Verdana,Arial,Helvetica,sans-serif;font-size:80%;}</style>\n"
							+ "<title>"
							+ rb.getString("announcement")
							+ ": "
							+ Validator.escapeHtml(hdr.getSubject())
							+ "</title>" + "</head>\n<body>");

			out.println("<h1>" + rb.getString("announcement") + "</h1>");

			// header
			out.println("<table><tr><td><b>" + rb.getString("from_colon") + "</b></td><td>"
					+ Validator.escapeHtml(hdr.getFrom().getDisplayName()) + "</td></tr>");
			out.println("<tr><td><b>" + rb.getString("date_colon") + "</b></td><td>" + Validator.escapeHtml(hdr.getDate().toStringLocalFull())
					+ "</td></tr>");
			out.println("<tr><td><b>" + rb.getString("subject_colon") + "</b></td><td>" + Validator.escapeHtml(hdr.getSubject()) + "</td></tr></table>");

			// body
			out.println("<p>" + Validator.escapeHtmlFormattedText(msg.getBody()) + "</p>");

			// attachments
			List attachments = hdr.getAttachments();
			if (attachments.size() > 0)
			{
				out.println("<p><b>" + rb.getString("attachments_colon") + "</b></p><p>");
				for (Iterator iAttachments = attachments.iterator(); iAttachments.hasNext();)
				{
					Reference attachment = (Reference) iAttachments.next();
					out.println("<a href=\"" + Validator.escapeHtml(attachment.getUrl()) + "\">"
							+ Validator.escapeHtml(attachment.getUrl()) + "</a><br />");
				}
				out.println("</p>");
			}

			out.println("</body></html>");
		}
		catch (PermissionException e)
		{
			throw new EntityPermissionException(e.getUser(), e.getLock(), e.getResource());
		}
	}

	/**
	 * {@inheritDoc}
	 */
	public HttpAccess getHttpAccess()
	{
		return new HttpAccess()
		{
			public void handleAccess(HttpServletRequest req, HttpServletResponse res, Reference ref, Collection copyrightAcceptedRefs)
				throws EntityPermissionException, EntityNotDefinedException //, EntityAccessOverloadException, EntityCopyrightException
			{
				// we only access the msg & rss reference
				if ( !REF_TYPE_MESSAGE.equals(ref.getSubType()) &&
					  !REF_TYPE_ANNOUNCEMENT_RSS.equals(ref.getSubType()) )
						throw new EntityNotDefinedException(ref.getReference());

				try
				{
					if ( REF_TYPE_MESSAGE.equals(ref.getSubType()) )
					{
						res.setContentType("text/html; charset=UTF-8");
						printAnnouncementHtml( res.getWriter(), ref );
					}
					else
					{
						res.setContentType("application/xml");
						res.setCharacterEncoding("UTF-8");
						printAnnouncementRss( res.getOutputStream(), ref );
					}
				}
				catch ( IOException e )
				{
					throw new EntityNotDefinedException(ref.getReference());
				}
			}
		};
	}

	/**********************************************************************************************************************************************************************************************************************************************************
	 * AnnouncementService implementation
	 *********************************************************************************************************************************************************************************************************************************************************/

	/**
	 * Return a specific announcement channel.
	 *
	 * @param ref
	 *        The channel reference.
	 * @return the AnnouncementChannel that has the specified name.
	 * @exception IdUnusedException
	 *            If this name is not defined for a announcement channel.
	 * @exception PermissionException
	 *            If the user does not have any permissions to the channel.
	 */
	public AnnouncementChannel getAnnouncementChannel(String ref) throws IdUnusedException, PermissionException
	{
		return (AnnouncementChannel) getChannel(ref);

	} // getAnnouncementChannel

	/**
	 * Add a new announcement channel.
	 *
	 * @param ref
	 *        The channel reference.
	 * @return The newly created channel.
	 * @exception IdUsedException
	 *            if the id is not unique.
	 * @exception IdInvalidException
	 *            if the id is not made up of valid characters.
	 * @exception PermissionException
	 *            if the user does not have permission to add a channel.
	 */
	public AnnouncementChannelEdit addAnnouncementChannel(String ref) throws IdUsedException, IdInvalidException,
			PermissionException
	{
		return (AnnouncementChannelEdit) addChannel(ref);

	} // addAnnouncementChannel

	/**
	 * Return a list of messages from the provided channel (merged flag returns merged messages)
	 * @param channelReference
	 *        Channel's reference String
	 * @param filter
	 *        A filtering object to accept messages, or null if no filtering is desired.
	 * @param order
	 *        Order of messages, ascending if true, descending if false
	 * @param merged
	 * 		  flag to include merged channel messages, true returns ALL messages including merged sites/channels
	 * @return a list of Message objects or specializations of Message objects (may be empty).
	 * @exception IdUnusedException
	 *            If this name is not defined for a announcement channel.
	 * @exception PermissionException
	 *            if the user does not have read permission to the channel.
	 * @exception NullPointerException
	 */
	public List getMessages(String channelReference,Filter filter, boolean order, boolean merged) throws IdUnusedException, PermissionException, NullPointerException
	{
		List<Message> messageList = new Vector();
		filter = new PrivacyFilter(filter);  		// filter out drafts this user cannot see
		Site site = null;
		String initMergeList = null;

		try{
			site = m_siteService.getSite(getAnnouncementChannel(channelReference).getContext());

			ToolConfiguration tc=site.getToolForCommonId(SAKAI_ANNOUNCEMENT_TOOL_ID);
			if (tc!=null){
				initMergeList = tc.getPlacementConfig().getProperty(PORTLET_CONFIG_PARM_MERGED_CHANNELS);
			}

			MergedList mergedAnnouncementList = new MergedList();
			String[] channelArrayFromConfigParameterValue = null;

			//get array of associated channels: similar logic as found in AnnouncementAction.getMessages() for viewing
			channelArrayFromConfigParameterValue = mergedAnnouncementList.getChannelReferenceArrayFromDelimitedString(channelReference, initMergeList);

			//get messages for each channel
			for(int i=0; i<channelArrayFromConfigParameterValue.length;i++)
			{
				MessageChannel siteChannel = getAnnouncementChannel(channelArrayFromConfigParameterValue[i]);
				if (siteChannel != null)
				{
					if (allowGetChannel(siteChannel.getReference()))
					{
						//merged flag = true then add all channel's messages
						//merged flag = false only add the calling channel's messages
						if(merged || siteChannel.getContext().equals(site.getId()))
								messageList.addAll(siteChannel.getMessages(filter,order));
					}
				}
			}

			//sort messages
			Collections.sort(messageList);
			if (!order)
			{
				Collections.reverse(messageList);
			}
		} catch (IdUnusedException e) {
			M_log.warn(e.getMessage());
		}
		catch (PermissionException e) {
			M_log.warn(e.getMessage());
		}
		catch (NullPointerException e) {
			M_log.warn(e.getMessage());
		}
		return messageList;

	} // getMessages

	/**********************************************************************************************************************************************************************************************************************************************************
	 * ResourceService implementation
	 *********************************************************************************************************************************************************************************************************************************************************/

	/**
	 * {@inheritDoc}
	 */
	public String getLabel()
	{
		return "announcement";
	}

        /**********************************************************************************************************************************************************************************************************************************************************
         * getSummaryFromHeader implementation
         *********************************************************************************************************************************************************************************************************************************************************/
         protected String getSummaryFromHeader(Message item, MessageHeader header)
         {
            String newText;
	    if ( header instanceof AnnouncementMessageHeader) {
		AnnouncementMessageHeader hdr = (AnnouncementMessageHeader) header;
		newText = hdr.getSubject();
	    } else {
       	      newText = item.getBody();
              if ( newText.length() > 50 ) newText = newText.substring(1,49);
            }
            newText = newText + ", " + header.getFrom().getDisplayName() + ", " + header.getDate().toStringLocalFull();
            return newText;
        }

	/**
	 * {@inheritDoc}
	 */
	public void transferCopyEntities(String fromContext, String toContext, List resourceIds)
	{
		transferCopyEntitiesRefMigrator(fromContext, toContext, resourceIds);
	}

	public Map<String, String> transferCopyEntitiesRefMigrator(String fromContext, String toContext, List resourceIds)
	{
	//	Map<String, String> transversalMap = new HashMap<String, String>();
		// get the channel associated with this site
		String oChannelRef = channelReference(fromContext, SiteService.MAIN_CONTAINER);
		AnnouncementChannel oChannel = null;
		try
		{
			oChannel = (AnnouncementChannel) getChannel(oChannelRef);
			// the "to" message channel
			String nChannelRef = channelReference(toContext, SiteService.MAIN_CONTAINER);
			AnnouncementChannel nChannel = null;
			try
			{
				nChannel = (AnnouncementChannel) getChannel(nChannelRef);
			}
			catch (IdUnusedException e)
			{
				try
				{
					commitChannel(addChannel(nChannelRef));

					try
					{
						nChannel = (AnnouncementChannel) getChannel(nChannelRef);
					}
					catch (Exception eee)
					{
						// ignore
					}
				}
				catch (Exception ee)
				{
					// ignore
				}
			}

			if (nChannel != null)
			{
				// pass the DOM to get new message ids, record the mapping from old to new, and adjust attachments
				List oMessageList = oChannel.getMessages(null, true);
				AnnouncementMessage oMessage = null;
				AnnouncementMessageHeader oMessageHeader = null;
				AnnouncementMessageEdit nMessage = null;
				for (int i = 0; i < oMessageList.size(); i++)
				{
					// the "from" message
					oMessage = (AnnouncementMessage) oMessageList.get(i);
					String oMessageId = oMessage.getId();

					boolean toBeImported = true;
					if (resourceIds != null && resourceIds.size() > 0)
					{
						toBeImported = false;
						for (int m = 0; m < resourceIds.size() && !toBeImported; m++)
						{
							if (((String) resourceIds.get(m)).equals(oMessageId))
							{
								toBeImported = true;
							}
						}
					}

					// not to import any assignment-generated announcement
					String assignmentReference = StringUtil.trimToNull(oMessage.getProperties().getProperty(AnnouncementService.ASSIGNMENT_REFERENCE));
					if (toBeImported && assignmentReference != null)
					{
						toBeImported = false;
					}

					if (toBeImported)
					{
						oMessageHeader = (AnnouncementMessageHeaderEdit) oMessage.getHeader();
						ResourceProperties oProperties = oMessage.getProperties();

						// the "to" message
						nMessage = (AnnouncementMessageEdit) nChannel.addMessage();
						nMessage.setBody(oMessage.getBody());
						// message header
						AnnouncementMessageHeaderEdit nMessageHeader = (AnnouncementMessageHeaderEdit) nMessage.getHeaderEdit();
						nMessageHeader.setDate(oMessageHeader.getDate());
						nMessageHeader.setMessage_order(oMessageHeader.getMessage_order());
						// when importing, refer to property to determine draft status
						if ("false".equalsIgnoreCase(m_serverConfigurationService.getString("import.importAsDraft")))
						{
							nMessageHeader.setDraft(oMessageHeader.getDraft());
						}
						else
						{
							nMessageHeader.setDraft(true);
						}

						nMessageHeader.setFrom(oMessageHeader.getFrom());
						nMessageHeader.setSubject(oMessageHeader.getSubject());
						// attachment
						List oAttachments = oMessageHeader.getAttachments();
						List nAttachments = m_entityManager.newReferenceList();
						for (int n = 0; n < oAttachments.size(); n++)
						{
							Reference oAttachmentRef = (Reference) oAttachments.get(n);
							String oAttachmentId = ((Reference) oAttachments.get(n)).getId();
							if (oAttachmentId.indexOf(fromContext) != -1)
							{
								// replace old site id with new site id in attachments
								String nAttachmentId = oAttachmentId.replaceAll(fromContext, toContext);
								try
								{
									ContentResource attachment = contentHostingService.getResource(nAttachmentId);
									nAttachments.add(m_entityManager.newReference(attachment.getReference()));
								}
								catch (IdUnusedException e)
								{
									try
									{
										ContentResource oAttachment = contentHostingService.getResource(oAttachmentId);
										try
										{
											if (contentHostingService.isAttachmentResource(nAttachmentId))
											{
												// add the new resource into attachment collection area
												ContentResource attachment = contentHostingService.addAttachmentResource(
														Validator.escapeResourceName(oAttachment.getProperties().getProperty(ResourceProperties.PROP_DISPLAY_NAME)),
														//toolManager.getCurrentPlacement().getContext(),
														toContext,    //don't use toolManager.getCurrentPlacement()!
														toolManager.getTool("sakai.announcements").getTitle(),
														oAttachment.getContentType(),
														oAttachment.getContent(),
														oAttachment.getProperties());
												// add to attachment list
												nAttachments.add(m_entityManager.newReference(attachment.getReference()));
											}
											else
											{
												// add the new resource into resource area
												ContentResource attachment = contentHostingService.addResource(
														Validator.escapeResourceName(oAttachment.getProperties().getProperty(ResourceProperties.PROP_DISPLAY_NAME)),
														//toolManager.getCurrentPlacement().getContext(),
														toContext, //don't use toolManager.getCurrentPlacement()!
														1,
														oAttachment.getContentType(),
														oAttachment.getContent(),
														oAttachment.getProperties(),
														NotificationService.NOTI_NONE);
												// add to attachment list
												nAttachments.add(m_entityManager.newReference(attachment.getReference()));
											}
										}
										catch (Exception eeAny)
										{
											// if the new resource cannot be added
											M_log.warn(" cannot add new attachment with id=" + nAttachmentId);
										}
									}
									catch (Exception eAny)
									{
										// if cannot find the original attachment, do nothing.
										M_log.warn(" cannot find the original attachment with id=" + oAttachmentId);
									}
								}
								catch (Exception any)
								{
									M_log.info(any.getMessage());
								}
							}
							else
							{
								nAttachments.add(oAttachmentRef);
							}
						}
						nMessageHeader.replaceAttachments(nAttachments);
						// properties
						ResourcePropertiesEdit p = nMessage.getPropertiesEdit();
						p.clear();
						p.addAll(oProperties);

						// complete the edit
						nChannel.commitMessage(nMessage, NotificationService.NOTI_IGNORE);

//						transversalMap.put(oMessage.getReference(), nMessage.getReference());
					}
				}

			} // if

			transferSynopticOptions(fromContext, toContext);
		}
		catch (IdUnusedException e)
		{
			M_log.warn(" MessageChannel " + fromContext + " cannot be found. ");
		}
		catch (Exception any)
		{
			M_log.warn(".importResources(): exception in handling " + serviceName() + " : ", any);
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	public void updateEntityReferences(String toContext, Map<String, String> transversalMap){
		if(transversalMap != null && transversalMap.size() > 0){
			try
			{
				Set<Entry<String, String>> entrySet = (Set<Entry<String, String>>) transversalMap.entrySet();

				String channelId = m_serverConfigurationService.getString(ANNOUNCEMENT_CHANNEL_PROPERTY, null);

				String toSiteId = toContext;

				if (channelId == null)
				{
					channelId = channelReference(toSiteId, SiteService.MAIN_CONTAINER);
					try
					{
						AnnouncementChannel aChannel = getAnnouncementChannel(channelId);
						//need to clear the cache to grab the newly saved messages
						m_threadLocalManager.set(aChannel.getReference() + ".msgs", null);
						List mList = aChannel.getMessages(null, true);

						for(Iterator iter = mList.iterator(); iter.hasNext();)
						{
							AnnouncementMessage msg = (AnnouncementMessage) iter.next();
							String msgBody = msg.getBody();
							boolean updated = false;
							Iterator<Entry<String, String>> entryItr = entrySet.iterator();
							while(entryItr.hasNext()) {
								Entry<String, String> entry = (Entry<String, String>) entryItr.next();
								String fromContextRef = entry.getKey();
								if(msgBody.contains(fromContextRef)){
									msgBody = msgBody.replace(fromContextRef, entry.getValue());
									updated = true;
								}
							}
							if(updated){
								AnnouncementMessageEdit editMsg = aChannel.editAnnouncementMessage(msg.getId());
								editMsg.setBody(msgBody);
								aChannel.commitMessage(editMsg, NotificationService.NOTI_IGNORE);
							}
						}
					}
					catch(Exception e)
					{
						M_log.debug("Unable to remove Announcements " + e);
					}
				}

			}
			catch (Exception e)
			{
				M_log.debug("transferCopyEntities: End removing Announcement data");
			}
		}
	}

	/**********************************************************************************************************************************************************************************************************************************************************
	 * AnnouncementChannel implementation
	 *********************************************************************************************************************************************************************************************************************************************************/

	public class BaseAnnouncementChannelEdit extends BaseMessageChannelEdit implements AnnouncementChannelEdit
	{
		/**
		 * Construct with a reference.
		 *
		 * @param ref
		 *        The channel reference.
		 */
		public BaseAnnouncementChannelEdit(String ref)
		{
			super(ref);

		} // BaseAnnouncementChannelEdit

		/**
		 * Construct as a copy of another message.
		 *
		 * @param other
		 *        The other message to copy.
		 */
		public BaseAnnouncementChannelEdit(MessageChannel other)
		{
			super(other);

		} // BaseAnnouncementChannelEdit

		/**
		 * Construct from a channel (and possibly messages) already defined in XML in a DOM tree. The Channel is added to storage.
		 *
		 * @param el
		 *        The XML DOM element defining the channel.
		 */
		public BaseAnnouncementChannelEdit(Element el)
		{
			super(el);

		} // BaseAnnouncementChannelEdit

		/**
		 * Return a specific announcement channel message, as specified by message name.
		 *
		 * @param messageId
		 *        The id of the message to get.
		 * @return the AnnouncementMessage that has the specified id.
		 * @exception IdUnusedException
		 *            If this name is not a defined message in this announcement channel.
		 * @exception PermissionException
		 *            If the user does not have any permissions to read the message.
		 */
		public AnnouncementMessage getAnnouncementMessage(String messageId) throws IdUnusedException, PermissionException
		{
			AnnouncementMessage msg = (AnnouncementMessage) getMessage(messageId);

			// filter out drafts not by this user (unless this user is a super user or has access_draft ability)
			if ((msg.getAnnouncementHeader()).getDraft() && (!m_securityService.isSuperUser())
					&& (!msg.getHeader().getFrom().getId().equals(m_sessionManager.getCurrentSessionUserId()))
					&& (!unlockCheck(SECURE_READ_DRAFT, msg.getReference())))
			{
				throw new PermissionException(m_sessionManager.getCurrentSessionUserId(), SECURE_READ, msg.getReference());
			}

			return msg;

		} // getAnnouncementMessage

		/**
		 * Return a list of all or filtered messages in the channel. The order in which the messages will be found in the iteration is by date, oldest first if ascending is true, newest first if ascending is false.
		 *
		 * @param filter
		 *        A filtering object to accept messages, or null if no filtering is desired.
		 * @param ascending
		 *        Order of messages, ascending if true, descending if false
		 * @return a list on channel Message objects or specializations of Message objects (may be empty).
		 * @exception PermissionException
		 *            if the user does not have read permission to the channel.
		 */
		public List getMessages(Filter filter, boolean ascending) throws PermissionException
		{
			// filter out drafts this user cannot see
			filter = new PrivacyFilter(filter);

			return super.getMessages(filter, ascending);

		} // getMessages

		/**
		 * A (AnnouncementMessageEdit) cover for editMessage. Return a specific channel message, as specified by message name, locked for update. Must commitEdit() to make official, or cancelEdit() when done!
		 *
		 * @param messageId
		 *        The id of the message to get.
		 * @return the Message that has the specified id.
		 * @exception IdUnusedException
		 *            If this name is not a defined message in this channel.
		 * @exception PermissionException
		 *            If the user does not have any permissions to read the message.
		 * @exception InUseException
		 *            if the current user does not have permission to mess with this user.
		 */
		public AnnouncementMessageEdit editAnnouncementMessage(String messageId) throws IdUnusedException, PermissionException,
				InUseException
		{
			return (AnnouncementMessageEdit) editMessage(messageId);

		} // editAnnouncementMessage

	/**
	 * A cover for removeMessage. Deletes the messages specified by the message id.
	 *
	 * @param messageId
	 *        The id of the message to get.
	 * @exception PermissionException
	 *            If the user does not have any permissions to delete the message.
	 */
		public void removeAnnouncementMessage(String messageId) throws PermissionException

		{
			removeMessage(messageId);
			//return (AnnouncementMessageEdit) removeMessage(messageId);

		} // editAnnouncementMessage

		/**
		 * A (AnnouncementMessageEdit) cover for addMessage. Add a new message to this channel. Must commitEdit() to make official, or cancelEdit() when done!
		 *
		 * @return The newly added message, locked for update.
		 * @exception PermissionException
		 *            If the user does not have write permission to the channel.
		 */
		public AnnouncementMessageEdit addAnnouncementMessage() throws PermissionException
		{
			return (AnnouncementMessageEdit) addMessage();

		} // addAnnouncementMessage

		/**
		 * a (AnnouncementMessage) cover for addMessage to add a new message to this channel.
		 *
		 * @param subject
		 *        The message header subject.
		 * @param draft
		 *        The message header draft indication.
		 * @param attachments
		 *        The message header attachments, a vector of Reference objects.
		 * @param body
		 *        The message body.
		 * @return The newly added message.
		 * @exception PermissionException
		 *            If the user does not have write permission to the channel.
		 */
		public AnnouncementMessage addAnnouncementMessage(String subject, boolean draft, List attachments, String body)
				throws PermissionException
		{
			AnnouncementMessageEdit edit = (AnnouncementMessageEdit) addMessage();
			AnnouncementMessageHeaderEdit header = edit.getAnnouncementHeaderEdit();
			edit.setBody(body);
			header.replaceAttachments(attachments);
			header.setSubject(subject);
			header.setDraft(draft);

			commitMessage(edit);

			return edit;

		} // addAnnouncementMessage

		//Intercept this commit to update the order and set unreleased to the top
		public void commitMessage(MessageEdit edit, int priority, String invokee) {
			int currentMax = setMessageOrderMax(edit);
			setMessageUnreleasedMax(currentMax);
			super.commitMessage(edit, priority, invokee);
		}

		/**
		 * used to set unreleased messages higher than other messages
		 *
		 * @param currentMax
		 *        The value of the current max
		 */
		private void setMessageUnreleasedMax(int currentMax) {
			boolean releaseDateFirst = m_serverConfigurationService.getBoolean("sakai.announcement.release_date_first", true);
			//Don't run this if the property is not set
			if (releaseDateFirst == false) {
				return;
			}
			try {
				//Get all messages in this channel
				List<MessageEdit> msglist = (List<MessageEdit>) this.getMessages(null, false);

				//Go through all the messages and move all the ones that aren't yet released higher in the order. Just ignore any errors
				for (MessageEdit me:msglist) {
					Date releaseDate = null;
					try {
						releaseDate = me.getProperties().getDateProperty(AnnouncementService.RELEASE_DATE);
					} catch (EntityPropertyNotDefinedException e) {
						if (M_log.isDebugEnabled()) {
							M_log.debug("Exception moving an unreleased item.",e);
						}
						continue;
					} catch (EntityPropertyTypeException e) {
						if (M_log.isDebugEnabled()) {
							M_log.debug("Exception moving an unreleased item.",e);
						}
						continue;
					}
					//releaseDate of this item is after current date, so set it later than max
					if (releaseDate.compareTo(new Date()) > 0) {
						if (M_log.isDebugEnabled()) {
							M_log.debug("Placing unreleased announcement to top of list " + me.getId());
						}
						//Try to set the current max of these other messages
						try {
							AnnouncementMessageEdit em = editAnnouncementMessage(me.getId());
							em.getHeaderEdit().setMessage_order(++currentMax);
							super.commitMessage(em, NotificationService.NOTI_IGNORE, "");
						} catch (InUseException e) {
							if (M_log.isDebugEnabled()) {
								M_log.debug("Exception moving an unreleased item.",e);
							}
							continue;
						}
						catch (IdUnusedException e) {
							if (M_log.isDebugEnabled()) {
								M_log.debug("Exception moving an unreleased item.",e);
							}
							continue;
						}
						//Commit this update directly
					}
				}
			} catch (PermissionException ex) {
				M_log.error(ex.getMessage());
			}
		}

		/**
		 * Go through all of the messages to find the max, put this message at the Maximum + 1
		 *
		 * @param msg
		 *        The message to edit
		 * @return The currentMax value determined (To save on future execution)
		 */
		private int setMessageOrderMax(MessageEdit msg) {
			int currentMax = 0;
			try {
				List<MessageEdit> msglist = (List<MessageEdit>) this.getMessages(null, false);
				for (MessageEdit me:msglist) {
					if (me.getHeaderEdit().getMessage_order()>currentMax)
						currentMax = me.getHeaderEdit().getMessage_order();
				}
				msg.getHeaderEdit().setMessage_order(++currentMax);
			} catch (PermissionException ex) {
				M_log.error(ex.getMessage());
			}
			return currentMax;
		}

	} // class BaseAnnouncementChannelEdit

	/**********************************************************************************************************************************************************************************************************************************************************
	 * AnnouncementMessage implementation
	 *********************************************************************************************************************************************************************************************************************************************************/

	public class BaseAnnouncementMessageEdit extends BaseMessageEdit implements AnnouncementMessageEdit
	{
		/**
		 * Construct.
		 *
		 * @param channel
		 *        The channel in which this message lives.
		 * @param id
		 *        The message id.
		 */
		public BaseAnnouncementMessageEdit(MessageChannel channel, String id)
		{
			super(channel, id);

		} // BaseAnnouncementMessageEdit

		/**
		 * Construct as a copy of another message.
		 *
		 * @param other
		 *        The other message to copy.
		 */
		public BaseAnnouncementMessageEdit(MessageChannel channel, Message other)
		{
			super(channel, other);

		} // BaseAnnouncementMessageEdit

		/**
		 * Construct from an existing definition, in xml.
		 *
		 * @param channel
		 *        The channel in which this message lives.
		 * @param el
		 *        The message in XML in a DOM element.
		 */
		public BaseAnnouncementMessageEdit(MessageChannel channel, Element el)
		{
			super(channel, el);

		} // BaseAnnouncementMessageEdit

		/**
		 * Access the announcement message header.
		 *
		 * @return The announcement message header.
		 */
		public AnnouncementMessageHeader getAnnouncementHeader()
		{
			return (AnnouncementMessageHeader) getHeader();

		} // getAnnouncementHeader

		/**
		 * Access the announcement message header.
		 *
		 * @return The announcement message header.
		 */
		public AnnouncementMessageHeaderEdit getAnnouncementHeaderEdit()
		{
			return (AnnouncementMessageHeaderEdit) getHeader();

		} // getAnnouncementHeaderEdit

	} // class BasicAnnouncementMessageEdit

	/**********************************************************************************************************************************************************************************************************************************************************
	 * AnnouncementMessageHeaderEdit implementation
	 *********************************************************************************************************************************************************************************************************************************************************/

	public class BaseAnnouncementMessageHeaderEdit extends BaseMessageHeaderEdit implements AnnouncementMessageHeaderEdit
	{
		/** The subject for the announcement. */
		protected String m_subject = null;

		/**
		 * Construct.
		 *
		 * @param id
		 *        The unique (within the channel) message id.
		 * @param from
		 *        The User who sent the message to the channel.
		 * @param attachments
		 *        The message header attachments, a vector of Reference objects.
		 */
		public BaseAnnouncementMessageHeaderEdit(Message msg, String id)
		{
			super(msg, id);

		} // BaseAnnouncementMessageHeaderEdit

		/**
		 * Construct, from an already existing XML DOM element.
		 *
		 * @param el
		 *        The header in XML in a DOM element.
		 */
		public BaseAnnouncementMessageHeaderEdit(Message msg, Element el)
		{
			super(msg, el);

			// extract the subject
			m_subject = el.getAttribute("subject");

		} // BaseAnnouncementMessageHeaderEdit

		/**
		 * Construct as a copy of another header.
		 *
		 * @param other
		 *        The other message header to copy.
		 */
		public BaseAnnouncementMessageHeaderEdit(Message msg, MessageHeader other)
		{
			super(msg, other);

			m_subject = ((AnnouncementMessageHeader) other).getSubject();

		} // BaseAnnouncementMessageHeaderEdit

		/**
		 * Access the subject of the announcement.
		 *
		 * @return The subject of the announcement.
		 */
		public String getSubject()
		{
			return ((m_subject == null) ? "" : m_subject);

		} // getSubject

		/**
		 * Set the subject of the announcement.
		 *
		 * @param subject
		 *        The subject of the announcement.
		 */
		public void setSubject(String subject)
		{
			if (StringUtil.different(subject, m_subject))
			{
				m_subject = subject;
			}

		} // setSubject

		/**
		 * Serialize the resource into XML, adding an element to the doc under the top of the stack element.
		 *
		 * @param doc
		 *        The DOM doc to contain the XML (or null for a string return).
		 * @param stack
		 *        The DOM elements, the top of which is the containing element of the new "resource" element.
		 * @return The newly added element.
		 */
		public Element toXml(Document doc, Stack stack)
		{
			// get the basic work done
			Element header = super.toXml(doc, stack);

			// add draft, subject
			header.setAttribute("subject", getSubject());
			header.setAttribute("draft", new Boolean(getDraft()).toString());

			return header;

		} // toXml

	} // BaseAnnouncementMessageHeader

	/**
	 * A filter that will reject announcement message drafts not from the current user, and otherwise use another filter, if defined, for acceptance.
	 */
	protected class PrivacyFilter implements Filter
	{
		/** The other filter to check with. May be null. */
		protected Filter m_filter = null;

		/**
		 * Construct
		 *
		 * @param filter
		 *        The other filter we check with.
		 */
		public PrivacyFilter(Filter filter)
		{
			m_filter = filter;

		} // PrivacyFilter

		/**
		 * Does this object satisfy the criteria of the filter?
		 *
		 * @return true if the object is accepted by the filter, false if not.
		 */
		public boolean accept(Object o)
		{
			// first if o is a announcement message that's a draft from another user, reject it
			if (o instanceof AnnouncementMessage)
			{
				AnnouncementMessage msg = (AnnouncementMessage) o;

				if ((msg.getAnnouncementHeader()).getDraft() && (!m_securityService.isSuperUser())
						&& (!msg.getHeader().getFrom().getId().equals(m_sessionManager.getCurrentSessionUserId()))
						&& (!unlockCheck(SECURE_READ_DRAFT, msg.getReference())))
				{
					return false;
				}
			}

			// now, use the real filter, if present
			if (m_filter != null) return m_filter.accept(o);

			return true;

		} // accept

	} // PrivacyFilter

	/* (non-Javadoc)
	 * @see org.sakaiproject.entity.api.EntitySummary#summarizableToolIds()
	 */
	public String[] summarizableToolIds()
	{
		return new String[] {
				"sakai.announcements",
				"sakai.motd"
		};
	}
	public String getSummarizableReference(String siteId, String toolIdentifier)
	{
		if ( "sakai.motd".equals(toolIdentifier) ) {
			return "/announcement/channel/!site/motd";
		} else {
			return super.getSummarizableReference(siteId, toolIdentifier);
		}
	}

	public void transferCopyEntities(String fromContext, String toContext, List ids, boolean cleanup)
	{
		transferCopyEntitiesRefMigrator(fromContext, toContext, ids, cleanup);
	}

	public Map<String, String> transferCopyEntitiesRefMigrator(String fromContext, String toContext, List ids, boolean cleanup)
	{
//		Map<String, String> transversalMap = new HashMap<String, String>();
		try
		{
			if(cleanup == true)
			{
				String channelId = m_serverConfigurationService.getString(ANNOUNCEMENT_CHANNEL_PROPERTY, null);

				String toSiteId = toContext;

				if (channelId == null)
				{
					channelId = channelReference(toSiteId, SiteService.MAIN_CONTAINER);
					try
					{
						AnnouncementChannel aChannel = getAnnouncementChannel(channelId);

						List mList = aChannel.getMessages(null, true);

						for(Iterator iter = mList.iterator(); iter.hasNext();)
						{
							AnnouncementMessage msg = (AnnouncementMessage) iter.next();

							aChannel.removeMessage(msg.getId());
						}
					}
					catch(Exception e)
					{
						M_log.debug("Unable to remove Announcements " + e);
					}
				}
			}
		}
		catch (Exception e)
		{
			M_log.debug("transferCopyEntities: End removing Announcement data");
		}
		transferCopyEntitiesRefMigrator(fromContext, toContext, ids);
		return null;
	}

	public void clearMessagesCache(String channelRef){
		m_threadLocalManager.set(channelRef + ".msgs", null);
	}
}

redpajama_set_name: RedPajamaGithub


text:
Home » Biography » Musetta Vander
Musetta Vander
Posted on Mar 3, 2021, Modified : Apr 1, 2021 Luniva
Why Is Musetta Vander Popular?
Musetta Vander is a well-known South African actress, model, and dancer who is popularly known for playing the role in a TV series "Super Force". She has been seen working actively on her career since the year, 1991.
Full Name Musetta Vander
Date of Birth 26 May 1963
Birth Place Durban, South Africa
Relationships Status Single
Profession Actress, Model
Ethnicity Dutch South Africans
Nationality South African
Where was Musetta Vander Born and Raised?
Musetta Vander, whose real name is Musetta van der Merwe was born on 26 May 1963 in Durban, South Africa. She has not mentioned her family and friends as she used to keep her personal life private. Currently, she is 57 years old and her zodiac sign is Gemini.
Vander holds a South African nationality and belongs to the ethnicity of Dutch South Africans.
Image Source: Alchetron
She has got a height of 5 feet 8 inches (1.73 m) and a weight of 57 kg. In addition, she has body measurements of 33-25-35 inches and has dark brown hair with green eyes.
Where did Vander go to School?
Earlier, she was seen doing her study on a Bachelor's degree in Communications and Psychology, and later, she was also seen appearing as anchor host for the MTV-like television show.
What is the relationship status of Musetta Vander?
Musetta Vander seems to be single as there is no rumor about dating and she also has not mentioned her love affair so currently, she is single.
Musetta Vander is active on Instagram with the tag name ("@musettavander") where she has 5486 followers. She is also active on Twitter with the tag name ("@MusettaVander") where she has 1252 followers.
Image Source:Mediaamazon
How did Musetta start her Career?
Musetta Vander started her film career after she had been cast as Christine Pickering on the movie "The Endangered" in 1989. In the same year, she was also seen playing the role of Sheri Cutler in the movie "Crimes of Crimes" and also seen as Marissa in the movie "The Revenger".
She started her television career after she had been cast as Zander Tyler on an American action-adventure TV series "Super Force" where she was seen appearing from the year pf 1991 to 1992. Her performance in the series made her earn more attention from the people and she became popular.
In 1993, she was seen appearing as Marissa in the movie "Monolith" and in the following year, she was cast as a Dancer on an American satirical comedy-drama movie "I'll Do Anything".
Further, Musetta Vander played the role of Juicy in the short movie "Dickwad" and then, also seen appearing as Lash on an American Western science fiction dark comedy movie "Oblivion" which was directed by Sam Irvin and was written by Peter David. In 1995, he was cast as Debbie on a science fiction horror movie "Project Metalbeast" which was directed by Alessandro de Gaetano. In that year, she was also seen appearing in the movies like "The Secret Force", "Project ShadowchaserII" and "Under the Hula Moon".
Likewise, she was seen appearing in the role of Lady Beryl in a fantasy movie "The Lord Protector: The Riddle of the Chosen" in 1996 which was directed by Ryan Carroll. In the same year, she was also seen playing the role of Lash on an American direct-to-video Space Western movie "Oblivion 2: Backlash" which was directed by Sam Irvin and was written by Peter David. Later, she was seen appearing in the movies including "American Hero", "Elissa", "Mortal Kombat: Annihilation", "Gunshy", "Molly", "Wild Wild Wild" alongside Holly Earl and Marin Ireland, "O Brother, Where Art Thou?", "The Cell", "Forbidden Warrior", "Mansquito", "Kicking & Screaming", "What's Up, Scarlet?", "Spymate", "Monster Night", "Say It in Russian" and "Planet Raptor".
In the year of 2009, Musetta Vander was cast as Teodora Van Sloan on an American comedy horror movie "Transylmania" which was directed by David and Scott Hillenbrand. In the same year, she was also seen appearing as Celia Hernandez in an action-thriller movie "Breaking Point" and also seen as Dr. Barbara Hale in a short movie "Napoleonic". In 2010, she was seen appearing as Julia Carter in the movie "Jonny" and later, she was seen playing the role of Angela Hausman is an American horror movie "Under the Bed" in 2012.
In addition, she was seen appearing in the movies like "5 Hours Friend", "Spreading Darkness", "The Better Half", "$elfie Shootout", "The Hatred" and "Shine".
In 1994, she was seen playing the role of Sharain Hourani on an American crime drama television series "Murder, She Wrote".
Further, she was seen appearing as Dominique on an American television sitcom" Boys Meets World" which was created and produced by Michael Jacobs and April Kelly in 1995. Later, she was seen appearing on several series like "Diagnosis: Murder", "Viper", "Highlander", "Buffy the Vampire Slyer", "Babylon 5", "Pensacola: Wings of Gold", "The Sentinel", "Soldier of Fortune, Inc", "Star Terck: Voyager", "Pensacola: Wings of Gold", "Secret Agent Man", "Stargate SG-1", "V.I.P", "Son of Beach", "Stargate SG-1", "She Spies" and "Frasier".
Likewise, she was seen playing the role of Princess Guinevere on an American television soap opera "The Bold and the Beautiful" which was created by William J. Bell and Lee Phillip Bell. In 2010, she was cast as Julie Merriweather on an American action procedural television series "NCIS". Further, she was also seen appearing as Miriam Nell on an American procedural television series "Criminal Minds: Beyond Borders" which was created by Erica Messer. In that year, she was also seen as Jennifer on an American-Swedish Comedy web television series "Swedish Dicks". In the year 2017, she was seen playing the role of Sheriff Alana Smith on an American action police procedural television series "Hawaii Five-0".
Further, she was seen playing the role of Emma in the play "Soweto's Burning" and then, also seen appearing on several music videos like "Let's Get Busy", "Bed of Nails", "Shotgun Sally", "I Live By the Groove", "This Old Heart of Mine", "I Don't Wanna Lose You", "Healing Hands", "Romance" Wiseblood", "Keep On Lovin' Me" and many more.
Image Source: Squarespace
What is the Current Net Worth of Vander?
Musetta Vander is a beautiful and hardworking woman who has been seen appearing in several fields and became successful in her career, has an estimated net worth of $1 million.
South African Actress
Irina Pantaeva
Iwan Rheon

redpajama_set_name: RedPajamaCommonCrawl


The most recent rage by poker aficionados and programmers would be to create and employ a texas holdem bot which will instantly play online poker with little if any human interaction, using the ultimate objective of winning money. This recent craze has alarmed both online poker sites and players because the anxiety about a pc program with the ability to win online poker will basically have the ability to outwit live thinking players of the hard-earned money and finally take advantage of the poker sites of quality players afraid to experience against a lot of poker bots.
A current industry study figured that 12% of online poker players were apprehensive about or had completely stopped playing online poker considering the current poker bot craze. That basically transmits players offline instead of risk their cash against these new computer-generated poker bots.
However, there are many methods to beat a texas holdem bot in online poker, and knowing these techniques will definitely provide the human player back the advantage against poker bots. One proven fact that constitutes a poker bot a much better player is they don't have the human emotion or power reasoning that the human must use when playing online poker. A texas holdem bot isn't apt to take 'tilt' or get angry when they're the sufferers of the bad beat.
In playing online poker, human players are facing two major advantages. The first is the pc generated code produced through the poker sites to find out shuffles, deals and connection between a hands, as the other disadvantage, just like harmful for your bankroll, may be the poker bot, that's pre-programmed with the statistics and odds from the game.
Nonetheless, you should use the pc-generated codes from the poker sites and poker bots against them if you know the way they work. A texas holdem bot is limited to creating decisions based exclusively around the play from the game regarding its record analysis of poker. Quite simply, a texas holdem bot is only going to decide according to known patterns hanging around.
Furthermore, the online poker sites, which positively make an effort to identify and thwart the efforts of poker bot programmers and users, have implemented a counter-measure towards the poker bots, utilizing the same known patterns. By applying a counter measure towards the poker bots, a texas holdem site has the capacity to make sure that a texas holdem bot won't win because the poker bots actions are foreseeable and limited to some skill-set proportional to record odds and probability.
This, as confusing as it might appear, really activly works to the benefit of a persons player. As the poker site's software programs are positively choosing the poker bot patterns and trying to identify who's an individual and who's a pc generated bot script, additionally they unintentionally implemented a flaw which enables an individual player to benefit from the online poker sites weakness.
The truth is, it has led to an individual player getting the opportunity to not just beat the poker bot, but beat human opponents too. By using a collection pattern the online poker sites are utilizing, a benefit is produced for anybody who understands that pattern. This pattern is actually a consecutive formula which formula dramatically has altered the poker game online to pressure wins and losses inside a set, specific and foreseeable pattern.
It isn't just plausible to conquer a texas holdem bot it's easily accomplished by recognizing the patterns utilized by online poker sites. These patterns are really simple to learn and wish little skill with a human player. So next time you consider playing poker online, think about using the codes and algorithms produced through the poker network to your benefit. They're there to avoid the poker bots from winning, although not you!


Extended Hours – The Law Library is open until 1am Monday-Friday until Dec. 15. We will continue to close at 11pm on Saturday.
Quiet Reading Room – The Quiet Reading Room in the northeast portion of the library's main floor is also available for study. This room is for law students only (so bring your ID card to swipe in) and quiet study will be enforced. We ask that you help us keep the noise down in there. This room is a good spot to take any take home exams.
Ear Plugs – We have a bowl of ear plugs near the 3rd floor library entrance for those looking for some additional quiet.
Stress Relief – For those of you that need a break from studying we've put a puzzle and some games in the Rex Lee Conversation Room.


text:
Latest Epstein accuser calls on Prince Andrew to talk to U.S. authorities
NEW YORK (Reuters) - A woman who accuses Jeffrey Epstein of sexually abusing her as a child on Monday said Britain's Prince Andrew should tell U.S. authorities what he knows about the financier.
"Jane Doe 15," a 31-year-old unidentified woman, who accuses the late financier Jeffrey Epstein of sexually abusing her when she was a child, speaks at a news conference in Los Angeles, California, November 18, 2019. REUTERS/Lucy Nicholson
"Prince Andrew, and any others who were close to Epstein, should come forward and give a statement under oath on what information they have," the woman, calling herself Jane Doe 15, said at a news conference with her lawyer Gloria Allred.
The woman on Monday became the latest of more than a dozen women to sue Epstein's estate, saying in her lawsuit that he subjected her to a "vicious, prolonged sexual assault" at his New Mexico ranch when she was 15.
Epstein, 66, hanged himself in jail in August while awaiting trial on federal sex trafficking charges. He had pleaded not guilty. Two days earlier he signed a will and put his estimated $577 million estate into a trust.
The financier once counted among his friends U.S. President Donald Trump, former President Bill Clinton and Prince Andrew.
In an interview on Saturday, Prince Andrew denied having sex with Virginia Giuffre, another of Epstein's alleged victims, who said in a previously filed lawsuit that she was trafficked by Epstein and forced to have sex with Prince Andrew when she was 17.
Lawyers for the estate's executors could not be reached for comment.
Epstein's brother and his lawyers have questioned a medical examiner's conclusion that his death was a suicide. Doe on Monday wore a bracelet with the words, "Epstein didn't kill himself."
Doe, who grew up in a poor family in the Midwest, met Epstein's secretary during a 2004 school trip to New York City. The secretary later invited her to view a magic show in Las Vegas and then fly to Epstein's New Mexico ranch in his private jet, the lawsuit said.
The secretary said Epstein was interested in helping girls who were in difficult circumstances, and when Doe arrived, Epstein summoned her to give him a massage alone, and then sexually assaulted her, the lawsuit said.
The executors Darren Indyke and Richard Kahn last week said they would seek to create a compensation fund for victims. The proposal must be approved by a court in the U.S. Virgin Islands, which is overseeing the estate.
Reporting by Brendan Pierson in New York; Editing by Noeleen Walder and Howard Goller


text:
Bishop Jennifer Baskerville-Burrows
Bishop's Staff
Waycross Camp & Conference Center
College Chaplaincies and Campus Ministries
LGBTQ Ministry
Union of Black Episcopalians
Episcopal Women's Ministries
Diaconal Ministry
Resources for Leaders
Transition Ministry
Commission on Ministry
College for Congregational Development
Pathways to Vitality
Faithful Innovation Initiative
Faithful Innovation Resources
Evangelism with Integrity
Spiritual Nurture
DonateDonate
Budget Formation Committee Calls for Program Proposals
March 18 deadline for new ministry ideas
Laurel Cornell, treasurer of the diocese, with the Rev. C. Davies Reed, Max Nottingham and Canon Brendan O'Sullivan-Hale at a budget formation committee meeting earlier this month.
Since she became bishop in 2017, Bishop Jennifer has urged the people of the diocese to commit both to a new mission and new ways of achieving it. "At our last diocesan convention, I invited you to dream dreams worthy of the reign of God," she said in November. "To try new things, risk failing, and get up and try again. That invitation still stands."
This winter, the Diocesan Budget Formation Committee accepted the invitation. Beginning in 2020, the budget of the diocese will be organized by new categories aligned with the five pillars of the diocese's mission, and the committee is calling for program proposals that take up the bishop's challenge to try new things.
The work of translating the diocesan mission into line items on a spreadsheet has not been easy, says Laurel Cornell, a member of Christ Church Cathedral who became diocesan treasurer in January. "It's tempting to just rename our old categories and fill them in with numbers, yet if we do only that we will have a budget that keeps us from acting on our new principles," she says. "We have funds sufficient to our needs. To figure out how to use those funds we must think deeply and consider prayerfully how we transform the broad principles into the lines of a specific budget."
According to Lara Dreyer, a member of Good Samaritan, Brownsburg, who serves on Executive Council, the budget committee is developing the new structure to incorporate several initiatives designed to help congregations build capacity for mission, including Faithful Innovation, the College for Congregational Development, which will begin in 2020, and the geographic reorganization of the diocese into neighborhoods.
"Most of our time, though, was focused on prayerful discernment around how the process and resulting budget can be a faithful response to our shared call to reach out with a radical welcome and bold witness to serve and transform our world," she said of the group's meeting earlier this month.
Greg Staab, a member and former senior warden of St. Matthew's, Indianapolis, is a new member of the budget committee. He has recently helped his parish develop a strategic plan that reaffirms its purpose and identity and has as its goal becoming financially sustainable without diocesan aid. His experience has helped the committee understand better the experience of congregations that rely on diocesan aid.
About a decade ago, St. Matthew's lost a long-term tenant whose rent payments balanced the parish's budget. The congregation's leaders turned to the diocese for help in what Staab called a "grudging process."
"We didn't like taking aid, but didn't have a plan to get sustainable," he said. "What we came down to is that we needed to extend ourselves outward to our community, heal, and grow within the congregation."
Today the congregation, which still relies on aid, is taking "baby steps," Staab said, and "moving in a positive direction."
The budget committee, he says, is interested in helping parishes like St. Matthew's "find a way to be sustainable on their own, while recognizing that there are probably some congregations that will need to continue to receive diocesan aid."
To that end, Staab, a veteran of the financial services industry, helped create a process to invite program proposals from congregations and ministries that have a new idea and would like diocesan funding to try it out.
"We want to make sure it's not a request for funds," he says. "It's more like, here's an idea that we want to do, molded around the vision of our ministry, and this program will help us accomplish that." The committee will accept budget proposals using the online form through March 18.
The budget that the committee presents to Executive Council later this year will undoubtedly look different from that of past years, but not all of the change will happen at once, says the Rev. C. Davies Reed, rector of St. Francis, Zionsville, and chair of the budget committee. He likens developing the new budget process to turning a ship.
"We're charting a new course, and it takes a while to get things in alignment. We'll take a few years to figure it out and experiment, but as with all experiments, some things will work and others won't, and then we'll try a different thing," he says. "The look and feel of the budget are going to continue to change to better align with our budget priorities."
"We can do anything, but not everything. And we're continuing to move from a position of scarcity to a position of abundance. We want all parishes to be healthy and able to do mission, and the resources that the diocese has can help us do that."
Bold Witness (5)
Homepage Featured (10)
In the World (4)
You Are Welcome (4)
1100 W 42nd St. Suite 235, Indianapolis, IN 46208
(317) 926-5454 / (800) 669-5786 © 2018 IndyDio
Diocesan Cycle of Prayer
Anglican Cycle of Prayer
The Lectionary


This is Doctor Rambo, I was the principal 3d artist on this project for a Gamejam of 46hours in montréal. We had 2 blueprints artists/ programmers, 1 vfx artist, 1 animator, 1 3d artist(me) and 1 sound designer. This is my 3rd game jam and by far the best one I've had. We totally learned a ton of things while having a blast in the past 46 hours.


text:
Parts of a Wristwatch
By: Tom Rose
How to Set the Time on a Rolex Daytona
How to Set a Citizen WR100 Watch
How to Replace the Watch Battery in a Dakota
Parts of a Watch Case
How to Change the Time on Tissot Watches
The watch is one of the oldest examples of personal technology that is still in use today. Unlike a cell phone, in which technology may be outdated in a few years, the wristwatch maintains many of the same components as the models that Louis Cartier popularized beginning in 1904.
A watchband can be made of metal, similar in appearance to a bracelet, or with two straps of leather or fabric, fastened by a clasp.
The case primarily provides a stable and clean place for the inner workings, but also allows for a stylish appearance. The back plate gives access to the movement and battery.
This crystal covers the dial. It is generally made of acrylic glass, mineral glass or synthetic sapphire, for extra scratch-resistance.
The dial contains the hands or digital output used to display the time. The dial can have many features, including the date, moon phase or additional time zones.
In a mechanical watch, the movement uses springs, wheels and gears to maintain the time. Digital and quartz watches use electrical circuits to display digits or power the gears that move the hands.
For analog watches, turning the crown will set the time and, if necessary, wind the mainspring. A digital watch uses push buttons to set the time and activate additional functions.
Glossary of Watch Parts
My name is Tom Rose and I am a freelance writer who has been able to leave the workplace completely. I now work strictly from home and it's all because of Demand Studios. My areas of expertise include Technology and the Arts, but because of the varied opportunities I've been presented, I see no limits to my ability to write confidently on virtually any topic.


text:
Rumination as a vulnerability factor to depression in adolescents in mainland China: Lifetime history of clinically significant depressive episodes
Wei Hong, John R.Z. Abela, Joseph R. Cohen, Dana M. Sheshko, Xiao Ting Shi, Anton van Hamel, Claire Starrs
The current study tested the vulnerability and sex differences hypotheses of the response styles theory of depression (Nolen-Hoeksema, 1991). Participants included 494 tenth-grade students (M = 15.25 years, SD = 0.47) recruited from two secondary schools in Beijing, China. Participants completed self-report measures assessing rumination and neuroticism as well as a semistructured clinical interview assessing current and past clinically significant depressive episodes. Higher levels of rumination were associated with a greater likelihood of exhibiting both a current depressive episode and a past history of depressive episodes even after controlling for neuroticism. Higher levels of rumination were also associated with greater severity and duration of current depressive episodes and greater severity of past depressive episodes even after controlling for neuroticism. Contrary to the sex differences hypothesis of the response styles theory, girls and boys did not differ in levels of rumination.
Journal of Clinical Child and Adolescent Psychology
Dive into the research topics of 'Rumination as a vulnerability factor to depression in adolescents in mainland China: Lifetime history of clinically significant depressive episodes'. Together they form a unique fingerprint.
Neuroticism Medicine & Life Sciences 100%
neuroticism Social Sciences 92%
China Medicine & Life Sciences 68%
vulnerability Social Sciences 67%
Depression Medicine & Life Sciences 55%
Sex Characteristics Medicine & Life Sciences 52%
Beijing Medicine & Life Sciences 31%
Self Report Medicine & Life Sciences 24%
Hong, W., Abela, J. R. Z., Cohen, J. R., Sheshko, D. M., Shi, X. T., van Hamel, A., & Starrs, C. (2010). Rumination as a vulnerability factor to depression in adolescents in mainland China: Lifetime history of clinically significant depressive episodes. Journal of Clinical Child and Adolescent Psychology, 39(6), 849-857. https://doi.org/10.1080/15374416.2010.517159
Rumination as a vulnerability factor to depression in adolescents in mainland China : Lifetime history of clinically significant depressive episodes. / Hong, Wei; Abela, John R.Z.; Cohen, Joseph R.; Sheshko, Dana M.; Shi, Xiao Ting; van Hamel, Anton; Starrs, Claire.
In: Journal of Clinical Child and Adolescent Psychology, Vol. 39, No. 6, 11.2010, p. 849-857.
Hong, W, Abela, JRZ, Cohen, JR, Sheshko, DM, Shi, XT, van Hamel, A & Starrs, C 2010, 'Rumination as a vulnerability factor to depression in adolescents in mainland China: Lifetime history of clinically significant depressive episodes', Journal of Clinical Child and Adolescent Psychology, vol. 39, no. 6, pp. 849-857. https://doi.org/10.1080/15374416.2010.517159
Hong W, Abela JRZ, Cohen JR, Sheshko DM, Shi XT, van Hamel A et al. Rumination as a vulnerability factor to depression in adolescents in mainland China: Lifetime history of clinically significant depressive episodes. Journal of Clinical Child and Adolescent Psychology. 2010 Nov;39(6):849-857. https://doi.org/10.1080/15374416.2010.517159
Hong, Wei ; Abela, John R.Z. ; Cohen, Joseph R. ; Sheshko, Dana M. ; Shi, Xiao Ting ; van Hamel, Anton ; Starrs, Claire. / Rumination as a vulnerability factor to depression in adolescents in mainland China : Lifetime history of clinically significant depressive episodes. In: Journal of Clinical Child and Adolescent Psychology. 2010 ; Vol. 39, No. 6. pp. 849-857.
@article{308ba6c57a9d4ff7b6e5699a72b8b43e,
title = "Rumination as a vulnerability factor to depression in adolescents in mainland China: Lifetime history of clinically significant depressive episodes",
abstract = "The current study tested the vulnerability and sex differences hypotheses of the response styles theory of depression (Nolen-Hoeksema, 1991). Participants included 494 tenth-grade students (M = 15.25 years, SD = 0.47) recruited from two secondary schools in Beijing, China. Participants completed self-report measures assessing rumination and neuroticism as well as a semistructured clinical interview assessing current and past clinically significant depressive episodes. Higher levels of rumination were associated with a greater likelihood of exhibiting both a current depressive episode and a past history of depressive episodes even after controlling for neuroticism. Higher levels of rumination were also associated with greater severity and duration of current depressive episodes and greater severity of past depressive episodes even after controlling for neuroticism. Contrary to the sex differences hypothesis of the response styles theory, girls and boys did not differ in levels of rumination.",
author = "Wei Hong and Abela, {John R.Z.} and Cohen, {Joseph R.} and Sheshko, {Dana M.} and Shi, {Xiao Ting} and {van Hamel}, Anton and Claire Starrs",
note = "Funding Information: The research reported in this article was supported by a research grant from the Social Sciences and Research Council of Canada awarded to John R. Z. Abela.",
journal = "Journal of clinical child psychology",
T1 - Rumination as a vulnerability factor to depression in adolescents in mainland China
T2 - Lifetime history of clinically significant depressive episodes
AU - Hong, Wei
AU - Abela, John R.Z.
AU - Cohen, Joseph R.
AU - Sheshko, Dana M.
AU - Shi, Xiao Ting
AU - van Hamel, Anton
AU - Starrs, Claire
N1 - Funding Information: The research reported in this article was supported by a research grant from the Social Sciences and Research Council of Canada awarded to John R. Z. Abela.
N2 - The current study tested the vulnerability and sex differences hypotheses of the response styles theory of depression (Nolen-Hoeksema, 1991). Participants included 494 tenth-grade students (M = 15.25 years, SD = 0.47) recruited from two secondary schools in Beijing, China. Participants completed self-report measures assessing rumination and neuroticism as well as a semistructured clinical interview assessing current and past clinically significant depressive episodes. Higher levels of rumination were associated with a greater likelihood of exhibiting both a current depressive episode and a past history of depressive episodes even after controlling for neuroticism. Higher levels of rumination were also associated with greater severity and duration of current depressive episodes and greater severity of past depressive episodes even after controlling for neuroticism. Contrary to the sex differences hypothesis of the response styles theory, girls and boys did not differ in levels of rumination.
AB - The current study tested the vulnerability and sex differences hypotheses of the response styles theory of depression (Nolen-Hoeksema, 1991). Participants included 494 tenth-grade students (M = 15.25 years, SD = 0.47) recruited from two secondary schools in Beijing, China. Participants completed self-report measures assessing rumination and neuroticism as well as a semistructured clinical interview assessing current and past clinically significant depressive episodes. Higher levels of rumination were associated with a greater likelihood of exhibiting both a current depressive episode and a past history of depressive episodes even after controlling for neuroticism. Higher levels of rumination were also associated with greater severity and duration of current depressive episodes and greater severity of past depressive episodes even after controlling for neuroticism. Contrary to the sex differences hypothesis of the response styles theory, girls and boys did not differ in levels of rumination.
JO - Journal of clinical child psychology
JF - Journal of clinical child psychology


The Economics of Climate Change for Malaysia (ECCM) project is study undertaken by the Government of Malaysia (GoM)– United Nations Development Programme (UNDP). The Economic Planning Unit, Prime Minister's Department (EPU) is the executing agency.
The results of the project can be used not only as a basis to prescribe mitigation and adaptation measures but also for Malaysia in positioning herself in any commitment under The United Nations Framework Convention on Climate Change (UNFCCC).
The policy options will help in identifying the appropriate response to climate change i.e. adaptation and mitigation and making sure the measures taken are in line with the national priorities. The inception period helped raise the awareness of key stakeholders and secure a high level of their participation. Through the ECCM study, several activities have been organised, including workshops and seminars to build the capacity of key members as well as stakeholders, examine the feasibility of economic models, database, and also explored the policy questions.
This Inception Report will discuss on the work done and provide a revised plan which consists of key tasks, an institutional approach for ECCM, and strategies to ensure that the project will meet its deadlines and the project objectives to move forward.
This report also contains annexes that specify details such as terms of reference (TOR) for the various management committees as well as project staff requirements and reports of activities held thus far.


UMBC's music department is known for pushing boundaries in new music – including its jazz studies program, headed up by director Matt Belzer – who's excelled as a teacher, composer and performer.
UMBC's jazz studies program is four years old now, and it boasts three official ensembles (including a "large" ensemble) and many unofficial student groups.
Jazz is woven into America's cultural fabric, but many people are still unfamiliar with or intimidated by jazz music.
Jazz culture has a lingo all its own that may seem impenetrable at first. The music also has a rich tradition in which its artists build on – and challenge – previous musicians and movements.
Improvisation is integral to jazz – flights of instrumental fancy that bend and reshape a song into individual expression. Understanding it, says Belzer, is key to appreciating the music.
"It's really about being as in the moment as you can," he says.
While Belzer says that exploring the standard "jazz repertoire" is one way for a new listener to go, he argues that exploring the world of jazz composition – music written specifically for jazz ensembles by great composers like Charles Mingus, Thelonious Monk or Duke Ellington – can reveal even more about the music.
"You're really getting that artist's view," says Belzer, who cites Herbie Hancock as an example of a dynamic jazz composer also known for his cover versions and explorations of other forms of music.
Belzer says hearing jazz at UMBC is a great place to start. The university's ensembles have regular concerts each semester – and there are also many student recitals. Growing into a greater appreciation of America's greatest indigenous art form can be as simple as strolling over to the Fine Arts Building.
This is a very popular choice and for good reason. Everything about this recording is transcendent. It's also a great introduction to Davis's long and varied career as well as to his sidemen.
I'm sure I'm not alone in feeling a spiritual connection to Wayne Shorter's music. His compositions and performances have been hugely influential, filled with magic and feeling.
If anyone represents the ability of jazz music to be appreciated intellectually, emotionally, spiritually, and viscerally, it's Charles Mingus.