From cad97c080651861bc07241acca92950ec958dac2 Mon Sep 17 00:00:00 2001
From: fgerlits <fgerlits@cfc7b370-4200-0410-a6e3-cb6bdb053afe>
Date: Fri, 15 Oct 2004 09:33:28 +0000
Subject: [PATCH] modified PlaylistElement to contain (a pointer to) an actual
 AudioClip instance, not just its ID

---
 .../modules/core/etc/playlistElement.xml      | 15 +++++
 .../core/include/LiveSupport/Core/AudioClip.h |  9 +--
 .../core/include/LiveSupport/Core/Playlist.h  |  6 +-
 .../LiveSupport/Core/PlaylistElement.h        | 33 ++++++-----
 .../LiveSupport/Core/StorageClientInterface.h | 16 +++++-
 livesupport/modules/core/src/AudioClip.cxx    |  9 ++-
 livesupport/modules/core/src/Playlist.cxx     | 19 +++----
 .../modules/core/src/PlaylistElement.cxx      | 37 ++++--------
 .../modules/core/src/PlaylistElementTest.cxx  |  7 ++-
 livesupport/modules/core/src/PlaylistTest.cxx | 22 +++++---
 .../modules/storage/src/TestStorageClient.h   | 27 ++++++++-
 .../storage/src/TestStorageClientTest.cxx     | 20 ++++++-
 .../storage/src/TestStorageClientTest.h       | 12 +++-
 .../src/AddAudioClipToPlaylistMethod.cxx      | 56 +++++++------------
 .../src/AddAudioClipToPlaylistMethod.h        | 17 +++---
 .../src/AddAudioClipToPlaylistMethodTest.cxx  |  4 +-
 .../src/CreatePlaylistMethodTest.cxx          |  4 +-
 .../src/OpenPlaylistForEditingMethod.cxx      |  9 +--
 .../src/OpenPlaylistForEditingMethod.h        |  8 +--
 .../src/OpenPlaylistForEditingMethodTest.cxx  |  4 +-
 .../products/scheduler/src/XmlRpcTools.cxx    |  9 ++-
 21 files changed, 193 insertions(+), 150 deletions(-)
 create mode 100644 livesupport/modules/core/etc/playlistElement.xml

diff --git a/livesupport/modules/core/etc/playlistElement.xml b/livesupport/modules/core/etc/playlistElement.xml
new file mode 100644
index 000000000..70fc1a6aa
--- /dev/null
+++ b/livesupport/modules/core/etc/playlistElement.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE playlistElement [
+
+<!ELEMENT playlistElement (audioClip) >
+<!ATTLIST playlistElement id              NMTOKEN     #REQUIRED >
+<!ATTLIST playlistElement relativeOffset  NMTOKEN     #REQUIRED >
+
+<!ELEMENT audioClip EMPTY >
+<!ATTLIST audioClip id              NMTOKEN     #REQUIRED >
+<!ATTLIST audioClip playlength      NMTOKEN     #REQUIRED >
+]>
+
+<playlistElement id="707" relativeOffset="00:12:34.000" >
+    <audioClip id="10001" playlength="01:00:00.000"/>
+</playlistElement>
diff --git a/livesupport/modules/core/include/LiveSupport/Core/AudioClip.h b/livesupport/modules/core/include/LiveSupport/Core/AudioClip.h
index 0809cc7e3..c3c20deeb 100644
--- a/livesupport/modules/core/include/LiveSupport/Core/AudioClip.h
+++ b/livesupport/modules/core/include/LiveSupport/Core/AudioClip.h
@@ -22,7 +22,7 @@
  
  
     Author   : $Author: fgerlits $
-    Version  : $Revision: 1.1 $
+    Version  : $Revision: 1.2 $
     Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/include/LiveSupport/Core/AudioClip.h,v $
 
 ------------------------------------------------------------------------------*/
@@ -72,7 +72,7 @@ using namespace boost::posix_time;
  *  in a Playlist.
  *
  *  @author  $Author: fgerlits $
- *  @version $Revision: 1.1 $
+ *  @version $Revision: 1.2 $
  */
 class AudioClip : public Configurable
 {
@@ -150,13 +150,10 @@ class AudioClip : public Configurable
          *  @param element the XML element to configure the object from.
          *  @exception std::invalid_argument if the supplied XML element
          *             contains bad configuraiton information
-         *  @exception std::logic_error if the object has already
-         *             been configured, and can not be reconfigured.
          */
         virtual void
         configure(const xmlpp::Element    & element)
-                                                throw (std::invalid_argument,
-                                                       std::logic_error);
+                                                throw (std::invalid_argument);
 
         /**
          *  Return the id of the audio clip.
diff --git a/livesupport/modules/core/include/LiveSupport/Core/Playlist.h b/livesupport/modules/core/include/LiveSupport/Core/Playlist.h
index 4e9bec2f7..4359fb7b1 100644
--- a/livesupport/modules/core/include/LiveSupport/Core/Playlist.h
+++ b/livesupport/modules/core/include/LiveSupport/Core/Playlist.h
@@ -22,7 +22,7 @@
  
  
     Author   : $Author: fgerlits $
-    Version  : $Revision: 1.4 $
+    Version  : $Revision: 1.5 $
     Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/include/LiveSupport/Core/Playlist.h,v $
 
 ------------------------------------------------------------------------------*/
@@ -71,7 +71,7 @@ using namespace boost::posix_time;
  *  the playlist.
  *
  *  @author  $Author: fgerlits $
- *  @version $Revision: 1.4 $
+ *  @version $Revision: 1.5 $
  */
 class Playlist : public Configurable
 {
@@ -284,7 +284,7 @@ class Playlist : public Configurable
          *             an audio clip with the same relative offset
          */
          void
-         addAudioClip(Ptr<UniqueId>::Ref       audioClipId,
+         addAudioClip(Ptr<AudioClip>::Ref      audioClip,
                       Ptr<time_duration>::Ref  relativeOffset)
                                                 throw (std::invalid_argument);
 };
diff --git a/livesupport/modules/core/include/LiveSupport/Core/PlaylistElement.h b/livesupport/modules/core/include/LiveSupport/Core/PlaylistElement.h
index cb6dc4c7f..d6f930894 100644
--- a/livesupport/modules/core/include/LiveSupport/Core/PlaylistElement.h
+++ b/livesupport/modules/core/include/LiveSupport/Core/PlaylistElement.h
@@ -22,7 +22,7 @@
  
  
     Author   : $Author: fgerlits $
-    Version  : $Revision: 1.2 $
+    Version  : $Revision: 1.3 $
     Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/include/LiveSupport/Core/PlaylistElement.h,v $
 
 ------------------------------------------------------------------------------*/
@@ -49,6 +49,7 @@
 #include "LiveSupport/Core/Ptr.h"
 #include "LiveSupport/Core/UniqueId.h"
 #include "LiveSupport/Core/Configurable.h"
+#include "LiveSupport/Core/AudioClip.h"
 
 
 namespace LiveSupport {
@@ -72,7 +73,7 @@ using namespace LiveSupport::Core;
  *  An item in a playlist.
  *
  *  @author  $Author: fgerlits $
- *  @version $Revision: 1.2 $
+ *  @version $Revision: 1.3 $
  */
 class PlaylistElement : public Configurable 
 {
@@ -93,9 +94,9 @@ class PlaylistElement : public Configurable
         Ptr<time_duration>::Ref     relativeOffset;
 
         /**
-         *  The id of the audio clip associated with the entry.
+         *  The audio clip associated with the entry.
          */
-        Ptr<UniqueId>::Ref          audioClipId;
+        Ptr<AudioClip>::Ref         audioClip;
 
 
     public:
@@ -119,12 +120,12 @@ class PlaylistElement : public Configurable
          */
         PlaylistElement(Ptr<UniqueId>::Ref       id,
                         Ptr<time_duration>::Ref  relativeOffset,
-                        Ptr<UniqueId>::Ref       audioClipId)
+                        Ptr<AudioClip>::Ref      audioClip)
                                                            throw ()
         {
             this->id             = id;
             this->relativeOffset = relativeOffset;
-            this->audioClipId    = audioClipId;
+            this->audioClip      = audioClip;
         }
 
         /**
@@ -137,12 +138,12 @@ class PlaylistElement : public Configurable
          *                                        the start of the playlist.
          */
         PlaylistElement(Ptr<time_duration>::Ref  relativeOffset,
-                        Ptr<UniqueId>::Ref       audioClipId)
+                        Ptr<AudioClip>::Ref      audioClip)
                                                            throw ()
         {
             this->id             = UniqueId::generateId();
             this->relativeOffset = relativeOffset;
-            this->audioClipId    = audioClipId;
+            this->audioClip      = audioClip;
         }
 
         /**
@@ -172,9 +173,7 @@ class PlaylistElement : public Configurable
          *
          *  @param element the XML element to configure the object from.
          *  @exception std::invalid_argument if the supplied XML element
-         *             contains bad configuraiton information
-         *  @exception std::logic_error if the object has already
-         *             been configured, and can not be reconfigured.
+         *             contains bad configuration information
          */
         virtual void
         configure(const xmlpp::Element    & element)
@@ -192,7 +191,7 @@ class PlaylistElement : public Configurable
         }
 
         /**
-         *  Return the relative offset of the element.
+         *  Return the relative offset of the playlist element.
          *
          *  @return the relative offset of the element.
          */
@@ -203,14 +202,14 @@ class PlaylistElement : public Configurable
         }
 
         /**
-         *  Return the id of the audio clip associated with the element.
+         *  Return the audio clip associated with the playlist element.
          *
-         *  @return the id of the audio clip associated with the element.
+         *  @return the audio clip associated with the element.
          */
-        Ptr<const UniqueId>::Ref
-        getAudioClipId(void) const                         throw ()
+        Ptr<const AudioClip>::Ref
+        getAudioClip(void) const                           throw ()
         {
-            return audioClipId;
+            return audioClip;
         }
 
 };
diff --git a/livesupport/modules/core/include/LiveSupport/Core/StorageClientInterface.h b/livesupport/modules/core/include/LiveSupport/Core/StorageClientInterface.h
index 031c4e2e4..1d5d8d5b4 100644
--- a/livesupport/modules/core/include/LiveSupport/Core/StorageClientInterface.h
+++ b/livesupport/modules/core/include/LiveSupport/Core/StorageClientInterface.h
@@ -22,7 +22,7 @@
  
  
     Author   : $Author: fgerlits $
-    Version  : $Revision: 1.5 $
+    Version  : $Revision: 1.6 $
     Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/include/LiveSupport/Core/Attic/StorageClientInterface.h,v $
 
 ------------------------------------------------------------------------------*/
@@ -61,7 +61,7 @@ namespace Core {
  *  An interface for storage clients.
  *
  *  @author  $Author: fgerlits $
- *  @version $Revision: 1.5 $
+ *  @version $Revision: 1.6 $
  */
 class StorageClientInterface
 {
@@ -130,6 +130,18 @@ class StorageClientInterface
         virtual const bool
         existsAudioClip(Ptr<const UniqueId>::Ref id) const       throw ()
                                                                         = 0;
+        /**
+         *  Return an audio clip with the specified id.
+         *
+         *  @param id the id of the playlist to return.
+         *  @return the requested audio clip.
+         *  @exception std::invalid_argument if no audio clip with the 
+         *             specified id exists.
+         */
+        virtual Ptr<AudioClip>::Ref
+        getAudioClip(Ptr<const UniqueId>::Ref id) const
+                                            throw (std::invalid_argument)
+                                                                        = 0;
 
 };
 
diff --git a/livesupport/modules/core/src/AudioClip.cxx b/livesupport/modules/core/src/AudioClip.cxx
index fefbe62f4..4c03f2621 100644
--- a/livesupport/modules/core/src/AudioClip.cxx
+++ b/livesupport/modules/core/src/AudioClip.cxx
@@ -22,7 +22,7 @@
  
  
     Author   : $Author: fgerlits $
-    Version  : $Revision: 1.1 $
+    Version  : $Revision: 1.2 $
     Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/src/AudioClip.cxx,v $
 
 ------------------------------------------------------------------------------*/
@@ -80,7 +80,7 @@ AudioClip :: configure(const xmlpp::Element    & element)
                                                              std::invalid_argument)
 {
     if (element.get_name() != configElementNameStr) {
-        std::string eMsg = "Bad configuration element ";
+        std::string eMsg = "bad configuration element ";
         eMsg += element.get_name();
         throw std::invalid_argument(eMsg);
     }
@@ -90,7 +90,7 @@ AudioClip :: configure(const xmlpp::Element    & element)
     unsigned long int           idValue;
 
     if (!(attribute = element.get_attribute(idAttrName))) {
-        std::string eMsg = "Missing attribute ";
+        std::string eMsg = "missing attribute ";
         eMsg += idAttrName;
         throw std::invalid_argument(eMsg);
     }
@@ -107,11 +107,10 @@ AudioClip :: configure(const xmlpp::Element    & element)
     title.reset(new std::string(titleValue));
 */
     if (!(attribute = element.get_attribute(playlengthAttrName))) {
-        std::string eMsg = "Missing attribute ";
+        std::string eMsg = "missing attribute ";
         eMsg += idAttrName;
         throw std::invalid_argument(eMsg);
     }
     playlength.reset(new time_duration(
                             duration_from_string(attribute->get_value())));
 }
-
diff --git a/livesupport/modules/core/src/Playlist.cxx b/livesupport/modules/core/src/Playlist.cxx
index 4fcee9f07..9371ac4d2 100644
--- a/livesupport/modules/core/src/Playlist.cxx
+++ b/livesupport/modules/core/src/Playlist.cxx
@@ -22,7 +22,7 @@
  
  
     Author   : $Author: fgerlits $
-    Version  : $Revision: 1.4 $
+    Version  : $Revision: 1.5 $
     Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/src/Playlist.cxx,v $
 
 ------------------------------------------------------------------------------*/
@@ -80,7 +80,7 @@ Playlist :: configure(const xmlpp::Element    & element)
                                             throw (std::invalid_argument)
 {
     if (element.get_name() != configElementNameStr) {
-        std::string eMsg = "Bad configuration element ";
+        std::string eMsg = "bad configuration element ";
         eMsg += element.get_name();
         throw std::invalid_argument(eMsg);
     }
@@ -90,7 +90,7 @@ Playlist :: configure(const xmlpp::Element    & element)
     unsigned long int           idValue;
 
     if (!(attribute = element.get_attribute(idAttrName))) {
-        std::string eMsg = "Missing attribute ";
+        std::string eMsg = "missing attribute ";
         eMsg += idAttrName;
         throw std::invalid_argument(eMsg);
     }
@@ -99,14 +99,13 @@ Playlist :: configure(const xmlpp::Element    & element)
     id.reset(new UniqueId(idValue));
 
     if (!(attribute = element.get_attribute(playlengthAttrName))) {
-        std::string eMsg = "Missing attribute ";
+        std::string eMsg = "missing attribute ";
         eMsg += idAttrName;
         throw std::invalid_argument(eMsg);
     }
     playlength.reset(new time_duration(
                             duration_from_string(attribute->get_value())));
 
-    // no exception thrown here: it's OK to have an empty playlist element list
     elementList.reset(new PlaylistElementListType);
     xmlpp::Node::NodeList  childNodes 
                            = element.get_children(elementListAttrName);
@@ -116,7 +115,7 @@ Playlist :: configure(const xmlpp::Element    & element)
         Ptr<PlaylistElement>::Ref  newPlaylistElement(new PlaylistElement);
         const xmlpp::Element       * childElement 
                                    = dynamic_cast<const xmlpp::Element*> (*it);
-        newPlaylistElement->configure(*childElement);
+        newPlaylistElement->configure(*childElement);    // may throw exception
         addPlaylistElement(newPlaylistElement);
         ++it;
     }
@@ -137,7 +136,7 @@ Playlist::addPlaylistElement(Ptr<PlaylistElement>::Ref playlistElement)
                                    = playlistElement->getRelativeOffset();
 
     if (elementList->find(*relativeOffset) != elementList->end()) {
-        std::string eMsg = "Two playlist elements at the same relative offset";
+        std::string eMsg = "two playlist elements at the same relative offset";
         throw std::invalid_argument(eMsg);
     }
 
@@ -149,17 +148,17 @@ Playlist::addPlaylistElement(Ptr<PlaylistElement>::Ref playlistElement)
  *  Add a new audio clip to the playlist.
  *----------------------------------------------------------------------------*/
 void
-Playlist::addAudioClip(Ptr<UniqueId>::Ref       audioClipId,
+Playlist::addAudioClip(Ptr<AudioClip>::Ref      audioClip,
                        Ptr<time_duration>::Ref  relativeOffset)
                                             throw (std::invalid_argument)
 {
     if (elementList->find(*relativeOffset) != elementList->end()) {
-        std::string eMsg = "Two playlist elements at the same relative offset";
+        std::string eMsg = "two playlist elements at the same relative offset";
         throw std::invalid_argument(eMsg);
     }
 
     Ptr<PlaylistElement>::Ref  playlistElement(new PlaylistElement(
-                                   relativeOffset, audioClipId));
+                                   relativeOffset, audioClip));
 
     (*elementList)[*relativeOffset] = playlistElement;
 }
diff --git a/livesupport/modules/core/src/PlaylistElement.cxx b/livesupport/modules/core/src/PlaylistElement.cxx
index 2a16cb78f..c5baf03d1 100644
--- a/livesupport/modules/core/src/PlaylistElement.cxx
+++ b/livesupport/modules/core/src/PlaylistElement.cxx
@@ -22,7 +22,7 @@
  
  
     Author   : $Author: fgerlits $
-    Version  : $Revision: 1.2 $
+    Version  : $Revision: 1.3 $
     Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/src/PlaylistElement.cxx,v $
 
 ------------------------------------------------------------------------------*/
@@ -67,11 +67,6 @@ static const std::string    relativeOffsetAttrName = "relativeOffset";
  */
 static const std::string    audioClipElementName = "audioClip";
 
-/**
- *  The name of the attribute of the id of the audio clip element.
- */
-static const std::string    audioClipIdAttrName = "id";
-
 
 /* ===============================================  local function prototypes */
 
@@ -86,7 +81,7 @@ PlaylistElement :: configure(const xmlpp::Element & element)
                                                 throw (std::invalid_argument)
 {
     if (element.get_name() != configElementNameStr) {
-        std::string eMsg = "Bad configuration element ";
+        std::string eMsg = "bad configuration element ";
         eMsg += element.get_name();
         throw std::invalid_argument(eMsg);
     }
@@ -96,7 +91,7 @@ PlaylistElement :: configure(const xmlpp::Element & element)
     UniqueId::IdType            idValue;
 
     if (!(attribute = element.get_attribute(idAttrName))) {
-        std::string eMsg = "Missing attribute ";
+        std::string eMsg = "missing attribute ";
         eMsg += idAttrName;
         throw std::invalid_argument(eMsg);
     }
@@ -105,7 +100,7 @@ PlaylistElement :: configure(const xmlpp::Element & element)
     id.reset(new UniqueId(idValue));
 
     if (!(attribute = element.get_attribute(relativeOffsetAttrName))) {
-        std::string eMsg = "Missing attribute ";
+        std::string eMsg = "missing attribute ";
         eMsg += relativeOffsetAttrName;
         throw std::invalid_argument(eMsg);
     }
@@ -117,32 +112,20 @@ PlaylistElement :: configure(const xmlpp::Element & element)
     xmlpp::Node::NodeList::iterator it = childNodes.begin();
 
     if (it == childNodes.end()) {
-        std::string eMsg = "Missing ";
+        std::string eMsg = "missing ";
         eMsg += audioClipElementName;
         eMsg += " XML element";
         throw std::invalid_argument(eMsg);
     }
 
-    const xmlpp::Element        * audioClipElement 
+    const xmlpp::Element      * audioClipElement 
                                 = dynamic_cast<const xmlpp::Element*> (*it);
-
-    if (!(attribute= audioClipElement->get_attribute(audioClipIdAttrName))) {
-        std::string eMsg = "Missing ";
-        eMsg += audioClipElementName;
-        eMsg += "attribute ";
-        eMsg += audioClipIdAttrName;
-        throw std::invalid_argument(eMsg);
-    }
-
-    std::stringstream           audioClipStrStr;
-    UniqueId::IdType            audioClipIdValue;
-    audioClipStrStr.str(attribute->get_value());
-    audioClipStrStr >> audioClipIdValue;
-    audioClipId.reset(new UniqueId(audioClipIdValue));
-
+    audioClip.reset(new AudioClip);
+    audioClip->configure(*audioClipElement);    // may throw exception
+    
     ++it;
     if (it != childNodes.end()) {
-        std::string eMsg = "More than one ";
+        std::string eMsg = "more than one ";
         eMsg += audioClipElementName;
         eMsg += " XML element";
         throw std::invalid_argument(eMsg);
diff --git a/livesupport/modules/core/src/PlaylistElementTest.cxx b/livesupport/modules/core/src/PlaylistElementTest.cxx
index 702b457af..e104c0fa0 100644
--- a/livesupport/modules/core/src/PlaylistElementTest.cxx
+++ b/livesupport/modules/core/src/PlaylistElementTest.cxx
@@ -22,7 +22,7 @@
  
  
     Author   : $Author: fgerlits $
-    Version  : $Revision: 1.1 $
+    Version  : $Revision: 1.2 $
     Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/src/PlaylistElementTest.cxx,v $
 
 ------------------------------------------------------------------------------*/
@@ -108,8 +108,9 @@ PlaylistElementTest :: firstTest(void)
         CPPUNIT_ASSERT(playlistElement->getId()->getId() == 707);
         Ptr<const time_duration>::Ref  relativeOffset
                                        = playlistElement->getRelativeOffset();
-        CPPUNIT_ASSERT(relativeOffset->total_seconds() == 12*60 + 34);
-        CPPUNIT_ASSERT(playlistElement->getAudioClipId()->getId() == 10001);
+        CPPUNIT_ASSERT(relativeOffset->total_seconds()   == 12*60 + 34);
+        CPPUNIT_ASSERT(playlistElement->getAudioClip()->getId()->getId()
+                                                         == 10001);
 
     } catch (std::invalid_argument &e) {
         std::string eMsg = "semantic error in configuration file:\n";
diff --git a/livesupport/modules/core/src/PlaylistTest.cxx b/livesupport/modules/core/src/PlaylistTest.cxx
index 57dd4373d..ef62115f8 100644
--- a/livesupport/modules/core/src/PlaylistTest.cxx
+++ b/livesupport/modules/core/src/PlaylistTest.cxx
@@ -22,7 +22,7 @@
  
  
     Author   : $Author: fgerlits $
-    Version  : $Revision: 1.4 $
+    Version  : $Revision: 1.5 $
     Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/src/PlaylistTest.cxx,v $
 
 ------------------------------------------------------------------------------*/
@@ -120,16 +120,18 @@ PlaylistTest :: firstTest(void)
     CPPUNIT_ASSERT(playlistElement->getId()->getId() == 101);
     Ptr<const time_duration>::Ref  relativeOffset 
                                    = playlistElement->getRelativeOffset();
-    CPPUNIT_ASSERT(relativeOffset->total_seconds() == 0);
-    CPPUNIT_ASSERT(playlistElement->getAudioClipId()->getId() == 10001);
+    CPPUNIT_ASSERT(relativeOffset->total_seconds()   == 0);
+    CPPUNIT_ASSERT(playlistElement->getAudioClip()->getId()->getId() 
+                                                     == 10001);
 
     ++it;
     CPPUNIT_ASSERT(it != playlist->end());
     playlistElement  = it->second;
     CPPUNIT_ASSERT(playlistElement->getId()->getId() == 102);
     relativeOffset   = playlistElement->getRelativeOffset();
-    CPPUNIT_ASSERT(relativeOffset->total_seconds() == 60 * 60);
-    CPPUNIT_ASSERT(playlistElement->getAudioClipId()->getId() == 10002);
+    CPPUNIT_ASSERT(relativeOffset->total_seconds()   == 60 * 60);
+    CPPUNIT_ASSERT(playlistElement->getAudioClip()->getId()->getId() 
+                                                     == 10002);
     
     ++it;
     CPPUNIT_ASSERT(it == playlist->end());
@@ -166,11 +168,14 @@ void
 PlaylistTest :: addAudioClipTest(void)
                                                 throw (CPPUNIT_NS::Exception)
 {
-    Ptr<UniqueId>::Ref       audioClipId(new UniqueId(20001));
+    Ptr<UniqueId>::Ref       clipId(new UniqueId(20001));
+    Ptr<time_duration>::Ref  clipLength(new time_duration(0,30,0,0));
+    Ptr<AudioClip>::Ref      audioClip(new AudioClip(clipId, clipLength));
+
     Ptr<time_duration>::Ref  relativeOffset(new time_duration(0,10,0,0));
                                                 // hour, min, sec, frac_sec
     try {
-        playlist->addAudioClip(audioClipId, relativeOffset);
+        playlist->addAudioClip(audioClip, relativeOffset);
     }
     catch (std::invalid_argument &e) {
         string eMsg = "addAudioClip returned with error: ";
@@ -183,7 +188,8 @@ PlaylistTest :: addAudioClipTest(void)
 
     ++it;
     Ptr<PlaylistElement>::Ref      playlistElement = it->second;
-    CPPUNIT_ASSERT(playlistElement->getAudioClipId()->getId() == 20001);
+    CPPUNIT_ASSERT(playlistElement->getAudioClip()->getId()->getId()
+                                                             == 20001);
 
     Ptr<const time_duration>::Ref  otherRelativeOffset 
                                    = playlistElement->getRelativeOffset();
diff --git a/livesupport/modules/storage/src/TestStorageClient.h b/livesupport/modules/storage/src/TestStorageClient.h
index d179be546..8f7bed3e7 100644
--- a/livesupport/modules/storage/src/TestStorageClient.h
+++ b/livesupport/modules/storage/src/TestStorageClient.h
@@ -22,7 +22,7 @@
  
  
     Author   : $Author: fgerlits $
-    Version  : $Revision: 1.5 $
+    Version  : $Revision: 1.6 $
     Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/src/TestStorageClient.h,v $
 
 ------------------------------------------------------------------------------*/
@@ -67,7 +67,7 @@ using namespace LiveSupport::Core;
  *  A dummy storage client, only used for test purposes.
  *
  *  @author  $Author: fgerlits $
- *  @version $Revision: 1.5 $
+ *  @version $Revision: 1.6 $
  */
 class TestStorageClient :
                     virtual public Configurable,
@@ -178,6 +178,7 @@ class TestStorageClient :
         virtual Ptr<Playlist>::Ref
         createPlaylist()                    throw ();
 
+
         /**
          *  Tell if an audio clip with a given id exists.
          *
@@ -193,6 +194,28 @@ class TestStorageClient :
             return true;
         }
 
+
+        /**
+         *  Return an audio clip with the specified id.
+         *
+         *  @param id the id of the audio clip to return.
+         *  @return the requested audio clip.
+         *  @exception std::invalid_argument if no audio clip with the 
+         *             specified id exists.
+         *  Note: at this point, this function returns a fake new audio
+         *        clip with play length 30 minutes.
+         */
+        virtual Ptr<AudioClip>::Ref
+        getAudioClip(Ptr<const UniqueId>::Ref id) const
+                                            throw (std::invalid_argument)
+        {
+            Ptr<UniqueId>::Ref       nonConstId(new UniqueId(id->getId()));
+            Ptr<time_duration>::Ref  length(new time_duration(0,30,0,0));
+            Ptr<AudioClip>::Ref      audioClip(new AudioClip(nonConstId,
+                                                             length));
+            return audioClip;
+        }
+
 };
 
 
diff --git a/livesupport/modules/storage/src/TestStorageClientTest.cxx b/livesupport/modules/storage/src/TestStorageClientTest.cxx
index 69fa3c9af..71711647d 100644
--- a/livesupport/modules/storage/src/TestStorageClientTest.cxx
+++ b/livesupport/modules/storage/src/TestStorageClientTest.cxx
@@ -22,7 +22,7 @@
  
  
     Author   : $Author: fgerlits $
-    Version  : $Revision: 1.4 $
+    Version  : $Revision: 1.5 $
     Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/src/TestStorageClientTest.cxx,v $
 
 ------------------------------------------------------------------------------*/
@@ -173,3 +173,21 @@ TestStorageClientTest :: createPlaylistTest(void)
 
     CPPUNIT_ASSERT(tsc->existsPlaylist(playlist->getId()));
 }
+
+
+/*------------------------------------------------------------------------------
+ *  Test to see if the fake audio clips are correctly counterfeited
+ *----------------------------------------------------------------------------*/
+void
+TestStorageClientTest :: audioClipTest(void)
+                                                throw (CPPUNIT_NS::Exception)
+{
+        Ptr<const UniqueId>::Ref  id(new UniqueId(rand()));
+
+        CPPUNIT_ASSERT(tsc->existsAudioClip(id));
+
+        Ptr<AudioClip>::Ref       audioClip = tsc->getAudioClip(id);
+        CPPUNIT_ASSERT(audioClip->getId()->getId() == id->getId());
+        CPPUNIT_ASSERT(audioClip->getPlaylength()->total_seconds()
+                                                   == 30*60);
+}
diff --git a/livesupport/modules/storage/src/TestStorageClientTest.h b/livesupport/modules/storage/src/TestStorageClientTest.h
index e9e5a83ea..1713316ca 100644
--- a/livesupport/modules/storage/src/TestStorageClientTest.h
+++ b/livesupport/modules/storage/src/TestStorageClientTest.h
@@ -22,7 +22,7 @@
  
  
     Author   : $Author: fgerlits $
-    Version  : $Revision: 1.4 $
+    Version  : $Revision: 1.5 $
     Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/src/TestStorageClientTest.h,v $
 
 ------------------------------------------------------------------------------*/
@@ -58,7 +58,7 @@ namespace Storage {
  *  Unit test for the UploadPlaylistMetohd class.
  *
  *  @author  $Author: fgerlits $
- *  @version $Revision: 1.4 $
+ *  @version $Revision: 1.5 $
  *  @see TestStorageClient
  */
 class TestStorageClientTest : public CPPUNIT_NS::TestFixture
@@ -110,6 +110,14 @@ class TestStorageClientTest : public CPPUNIT_NS::TestFixture
         void
         createPlaylistTest(void)                throw (CPPUNIT_NS::Exception);
 
+        /**
+         *  Testing existsAudioClip() and getAudioClip().
+         *
+         *  @exception CPPUNIT_NS::Exception on test failures.
+         */
+        void
+        audioClipTest(void)                     throw (CPPUNIT_NS::Exception);
+
 
     public:
         
diff --git a/livesupport/products/scheduler/src/AddAudioClipToPlaylistMethod.cxx b/livesupport/products/scheduler/src/AddAudioClipToPlaylistMethod.cxx
index bb4194ee3..b7e4f50f4 100644
--- a/livesupport/products/scheduler/src/AddAudioClipToPlaylistMethod.cxx
+++ b/livesupport/products/scheduler/src/AddAudioClipToPlaylistMethod.cxx
@@ -22,7 +22,7 @@
  
  
     Author   : $Author: fgerlits $
-    Version  : $Revision: 1.1 $
+    Version  : $Revision: 1.2 $
     Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/AddAudioClipToPlaylistMethod.cxx,v $
 
 ------------------------------------------------------------------------------*/
@@ -107,35 +107,15 @@ AddAudioClipToPlaylistMethod :: execute(XmlRpc::XmlRpcValue  & parameters,
     }
 
     Ptr<UniqueId>::Ref       playlistId;
-    try{
-        playlistId = XmlRpcTools::extractPlaylistId(parameters);
-    }
-    catch (std::invalid_argument &e) {
-        XmlRpcTools::markError(errorId+2, 
-                               "missing playlist ID argument", 
-                               returnValue);
-        return;
-    }
-
     Ptr<UniqueId>::Ref       audioClipId;
-    try{
-        audioClipId = XmlRpcTools::extractAudioClipId(parameters);
-    }
-    catch (std::invalid_argument &e) {
-        XmlRpcTools::markError(errorId+3, 
-                               "missing audio clip ID argument", 
-                               returnValue);
-        return;
-    }
-
     Ptr<time_duration>::Ref  relativeOffset;
     try{
+        playlistId = XmlRpcTools::extractPlaylistId(parameters);
+        audioClipId = XmlRpcTools::extractAudioClipId(parameters);
         relativeOffset = XmlRpcTools::extractRelativeOffset(parameters);
     }
     catch (std::invalid_argument &e) {
-        XmlRpcTools::markError(errorId+4, 
-                               "missing relative offset argument", 
-                               returnValue);
+        XmlRpcTools::markError(errorId+2, e.what(), returnValue);
         return;
     }
 
@@ -144,34 +124,40 @@ AddAudioClipToPlaylistMethod :: execute(XmlRpc::XmlRpcValue  & parameters,
     scf     = StorageClientFactory::getInstance();
     storage = scf->getStorageClient();
  
-    if (!storage->existsPlaylist(playlistId)) {
-        XmlRpcTools::markError(errorId+5, "playlist does not exist", 
-                               returnValue);
-        return;
-    }
-
     Ptr<Playlist>::Ref playlist;
     try {
         playlist = storage->getPlaylist(playlistId);
     }
-    catch (std::invalid_argument &e) {           // this should never happen
-        XmlRpcTools::markError(errorId+6, "could not load playlist", 
+    catch (std::invalid_argument &e) {
+        XmlRpcTools::markError(errorId+3, "playlist does not exist", 
                                returnValue);
         return;
     }
 
     if (!playlist->getIsLockedForEditing()) {
-        XmlRpcTools::markError(errorId+7, 
+        XmlRpcTools::markError(errorId+4, 
                                "playlist has not been opened for editing", 
                                returnValue);
         return;
     }
 
+    Ptr<AudioClip>::Ref audioClip;
+    try {
+        audioClip = storage->getAudioClip(audioClipId);
+    }
+    catch (std::invalid_argument &e) {
+        XmlRpcTools::markError(errorId+5, "audio clip does not exist", 
+                               returnValue);
+        return;
+    }
+
     try {                                        // and finally, the beef
-        playlist->addAudioClip(audioClipId, relativeOffset);
+        playlist->addAudioClip(audioClip, relativeOffset);
     }
     catch(std::invalid_argument &e) {
-        XmlRpcTools::markError(errorId+8, e.what(), returnValue);
+        XmlRpcTools::markError(errorId+6,
+                               "two audio clips at the same relative offset",
+                               returnValue);
         return;
     }
 }
diff --git a/livesupport/products/scheduler/src/AddAudioClipToPlaylistMethod.h b/livesupport/products/scheduler/src/AddAudioClipToPlaylistMethod.h
index 1b73ce55c..88b14ca10 100644
--- a/livesupport/products/scheduler/src/AddAudioClipToPlaylistMethod.h
+++ b/livesupport/products/scheduler/src/AddAudioClipToPlaylistMethod.h
@@ -22,7 +22,7 @@
  
  
     Author   : $Author: fgerlits $
-    Version  : $Revision: 1.1 $
+    Version  : $Revision: 1.2 $
     Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/AddAudioClipToPlaylistMethod.h,v $
 
 ------------------------------------------------------------------------------*/
@@ -88,17 +88,14 @@ using namespace LiveSupport::Core;
  *  The possible error codes are:
  *  <ul>
  *     <li>301 - invalid argument format </li>
- *     <li>301 - missing playlist ID argument </li>
- *     <li>301 - missing audio clip ID argument </li>
- *     <li>301 - missing relative offset argument </li>
- *     <li>301 - playlist does not exist </li>
- *     <li>301 - could not load playlist </li>
- *     <li>301 - playlist has not been opened for editing </li>
- *     <li>301 - two audio clips at the same relative offset
- *               (from Playlist::addAudioClipToPlaylist()) </li>
+ *     <li>302 - missing ... argument </li>
+ *     <li>303 - playlist does not exist </li>
+ *     <li>304 - playlist has not been opened for editing </li>
+ *     <li>305 - audio clip does not exist </li>
+ *     <li>306 - two audio clips at the same relative offset</li>
  *  </ul>
  *  @author  $Author: fgerlits $
- *  @version $Revision: 1.1 $
+ *  @version $Revision: 1.2 $
  */
 class AddAudioClipToPlaylistMethod : public XmlRpc::XmlRpcServerMethod
 {
diff --git a/livesupport/products/scheduler/src/AddAudioClipToPlaylistMethodTest.cxx b/livesupport/products/scheduler/src/AddAudioClipToPlaylistMethodTest.cxx
index 082be8435..75d81fd29 100644
--- a/livesupport/products/scheduler/src/AddAudioClipToPlaylistMethodTest.cxx
+++ b/livesupport/products/scheduler/src/AddAudioClipToPlaylistMethodTest.cxx
@@ -22,7 +22,7 @@
  
  
     Author   : $Author: fgerlits $
-    Version  : $Revision: 1.1 $
+    Version  : $Revision: 1.2 $
     Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/AddAudioClipToPlaylistMethodTest.cxx,v $
 
 ------------------------------------------------------------------------------*/
@@ -157,7 +157,7 @@ AddAudioClipToPlaylistMethodTest :: firstTest(void)
     openPlaylistMethod->execute(parameter, result);
     addAudioClipMethod->execute(parameter, result);
     CPPUNIT_ASSERT(result.hasMember("errorCode"));
-    CPPUNIT_ASSERT((int)(result["errorCode"]) == 308);
+    CPPUNIT_ASSERT((int)(result["errorCode"]) == 306);
 
     parameter.clear();
     result.clear();
diff --git a/livesupport/products/scheduler/src/CreatePlaylistMethodTest.cxx b/livesupport/products/scheduler/src/CreatePlaylistMethodTest.cxx
index edc1dfb4c..945d91d4d 100644
--- a/livesupport/products/scheduler/src/CreatePlaylistMethodTest.cxx
+++ b/livesupport/products/scheduler/src/CreatePlaylistMethodTest.cxx
@@ -22,7 +22,7 @@
  
  
     Author   : $Author: fgerlits $
-    Version  : $Revision: 1.4 $
+    Version  : $Revision: 1.5 $
     Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/CreatePlaylistMethodTest.cxx,v $
 
 ------------------------------------------------------------------------------*/
@@ -158,5 +158,5 @@ CreatePlaylistMethodTest :: firstTest(void)
     method->execute(parameter, result);
     CPPUNIT_ASSERT((int) result["errorCode"] == 105);
     CPPUNIT_ASSERT((const std::string) result["errorMessage"] ==
-                              "playlist could not be opened (already open?)");
+                        "could not open playlist for editing (already open?)");
 }
diff --git a/livesupport/products/scheduler/src/OpenPlaylistForEditingMethod.cxx b/livesupport/products/scheduler/src/OpenPlaylistForEditingMethod.cxx
index 9dd585320..f21125178 100644
--- a/livesupport/products/scheduler/src/OpenPlaylistForEditingMethod.cxx
+++ b/livesupport/products/scheduler/src/OpenPlaylistForEditingMethod.cxx
@@ -22,7 +22,7 @@
  
  
     Author   : $Author: fgerlits $
-    Version  : $Revision: 1.4 $
+    Version  : $Revision: 1.5 $
     Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/OpenPlaylistForEditingMethod.cxx,v $
 
 ------------------------------------------------------------------------------*/
@@ -133,14 +133,15 @@ OpenPlaylistForEditingMethod :: execute(XmlRpc::XmlRpcValue  & parameters,
         playlist = storage->getPlaylist(id);
     }
     catch (std::invalid_argument &e) {
-        XmlRpcTools::markError(errorId+4, "could not open playlist", 
+        XmlRpcTools::markError(errorId+4, "could not load playlist", 
                                returnValue);
         return;
     }
 
     if (!playlist->setLockedForEditing(true)) {
-        XmlRpcTools::markError(errorId+5, "playlist could not be opened (already open?)", 
-                               returnValue);
+        XmlRpcTools::markError(errorId+5, 
+                "could not open playlist for editing (already open?)", 
+                returnValue);
         return;
     }
 
diff --git a/livesupport/products/scheduler/src/OpenPlaylistForEditingMethod.h b/livesupport/products/scheduler/src/OpenPlaylistForEditingMethod.h
index fd03087cf..6ad846a63 100644
--- a/livesupport/products/scheduler/src/OpenPlaylistForEditingMethod.h
+++ b/livesupport/products/scheduler/src/OpenPlaylistForEditingMethod.h
@@ -22,7 +22,7 @@
  
  
     Author   : $Author: fgerlits $
-    Version  : $Revision: 1.3 $
+    Version  : $Revision: 1.4 $
     Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/OpenPlaylistForEditingMethod.h,v $
 
 ------------------------------------------------------------------------------*/
@@ -93,11 +93,11 @@ using namespace LiveSupport::Core;
  *     <li>101 - invalid argument format</li>
  *     <li>102 - argument is not a playlist ID</li>
  *     <li>103 - playlist does not exist</li>
- *     <li>104 - could not open playlist</li>
- *     <li>105 - playlist could not be opened (already open?)</li>
+ *     <li>104 - could not load playlist</li>
+ *     <li>105 - could not open playlist for editing (already open?)</li>
  *  </ul>
  *  @author  $Author: fgerlits $
- *  @version $Revision: 1.3 $
+ *  @version $Revision: 1.4 $
  */
 class OpenPlaylistForEditingMethod : public XmlRpc::XmlRpcServerMethod
 {
diff --git a/livesupport/products/scheduler/src/OpenPlaylistForEditingMethodTest.cxx b/livesupport/products/scheduler/src/OpenPlaylistForEditingMethodTest.cxx
index 1e8818f0a..dbb31df1d 100644
--- a/livesupport/products/scheduler/src/OpenPlaylistForEditingMethodTest.cxx
+++ b/livesupport/products/scheduler/src/OpenPlaylistForEditingMethodTest.cxx
@@ -22,7 +22,7 @@
  
  
     Author   : $Author: fgerlits $
-    Version  : $Revision: 1.4 $
+    Version  : $Revision: 1.5 $
     Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/OpenPlaylistForEditingMethodTest.cxx,v $
 
 ------------------------------------------------------------------------------*/
@@ -168,6 +168,6 @@ OpenPlaylistForEditingMethodTest :: firstTest(void)
     method->execute(parameter, result);
     CPPUNIT_ASSERT((int) result["errorCode"] == 105);
     CPPUNIT_ASSERT((const std::string) result["errorMessage"] ==
-                               "playlist could not be opened (already open?)");
+                        "could not open playlist for editing (already open?)");
 
 }
diff --git a/livesupport/products/scheduler/src/XmlRpcTools.cxx b/livesupport/products/scheduler/src/XmlRpcTools.cxx
index b850b8fd5..9a349d91d 100644
--- a/livesupport/products/scheduler/src/XmlRpcTools.cxx
+++ b/livesupport/products/scheduler/src/XmlRpcTools.cxx
@@ -22,7 +22,7 @@
  
  
     Author   : $Author: fgerlits $
-    Version  : $Revision: 1.2 $
+    Version  : $Revision: 1.3 $
     Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/Attic/XmlRpcTools.cxx,v $
 
 ------------------------------------------------------------------------------*/
@@ -87,7 +87,7 @@ XmlRpcTools :: extractPlaylistId(XmlRpc::XmlRpcValue & xmlRpcValue)
                                                 throw (std::invalid_argument)
 {
     if (!xmlRpcValue.hasMember(playlistIdName)) {
-        throw std::invalid_argument("no playlist id in parameter structure");
+        throw std::invalid_argument("missing playlist ID");
     }
 
     Ptr<UniqueId>::Ref id(new UniqueId((int) xmlRpcValue[playlistIdName]));
@@ -103,7 +103,7 @@ XmlRpcTools :: extractAudioClipId(XmlRpc::XmlRpcValue & xmlRpcValue)
                                                 throw (std::invalid_argument)
 {
     if (!xmlRpcValue.hasMember(audioClipIdName)) {
-        throw std::invalid_argument("no audio clip id in parameter structure");
+        throw std::invalid_argument("missing audio clip ID");
     }
 
     Ptr<UniqueId>::Ref id(new UniqueId((int) xmlRpcValue[audioClipIdName]));
@@ -119,8 +119,7 @@ XmlRpcTools :: extractRelativeOffset(XmlRpc::XmlRpcValue & xmlRpcValue)
                                                 throw (std::invalid_argument)
 {
     if (!xmlRpcValue.hasMember(relativeOffsetName)) {
-        throw std::invalid_argument("no relative offset "
-                                     "in parameter structure");
+        throw std::invalid_argument("missing relative offset");
     }
 
     Ptr<time_duration>::Ref relativeOffset(new time_duration(0,0,