void SwapFieldElementCommand::undo(void)
{
    Inherited::undo();

    EditFieldHandlePtr TheFieldHandle = _FC->editField(_FieldId);
    if(TheFieldHandle->isPointerField())
    {
        EditMFieldHandle<FieldContainerPtrMFieldBase>* TheHandle(dynamic_cast<EditMFieldHandle<FieldContainerPtrMFieldBase>*>(TheFieldHandle.get()));
        FieldContainer* ToFC = TheHandle->get(_ToIndex);
        FieldContainer* FromFC = TheHandle->get(_FromIndex);

        TheHandle->replace(_FromIndex, ToFC);
        TheHandle->replace(_ToIndex, FromFC);
    }
    else
    {
        //Get the to index value
        std::ostringstream StrStream;
        OutStream TheOutStream(StrStream);

        TheFieldHandle->pushIndexedValueToStream(TheOutStream, _ToIndex);
        std::string ToValue = StrStream.str();

        //Get the from index value
        StrStream.clear();
        StrStream.str("");
        TheFieldHandle->pushIndexedValueToStream(TheOutStream, _FromIndex);
        std::string FromValue = StrStream.str();

        //Set the value
        TheFieldHandle->pushIndexedValueFromCString(ToValue.c_str(), _FromIndex);
        TheFieldHandle->pushIndexedValueFromCString(FromValue.c_str(), _ToIndex);
    }

}
void SwapFieldElementCommand::execute(void)
{
    //Check for a valid Field Container
    if(_FC == NULL)
    {
        SWARNING << "FieldContainer is NULL." << std::endl;
        return;
    }

    //Check for valid Field
    EditFieldHandlePtr TheFieldHandle = _FC->editField(_FieldId);
    if(!TheFieldHandle->isValid())
    {
        SWARNING << "No Field with Id: " << _FieldId << " in FieldContainers of type " << _FC->getType().getName() << std::endl;
        return;
    }

    //Check for valid Field cardinality
    if(TheFieldHandle->getCardinality() != FieldType::MultiField)
    {
        SWARNING << "Field: " << _FC->getType().getName() << " is not a MultiField" << std::endl;
        return;
    }

    //Check for valid indexing
    if(TheFieldHandle->getCardinality() == FieldType::MultiField && _FromIndex >= TheFieldHandle->size())
    {
        SWARNING << "Cannot move the value of from index " << _FromIndex << ", on field " << TheFieldHandle->getDescription()->getName() 
                 << ", on FieldContianer of type " << _FC->getType().getName()
                 << " because that field has size " << TheFieldHandle->size() << std::endl;
        return;
    }
    if(TheFieldHandle->getCardinality() == FieldType::MultiField && _ToIndex >= TheFieldHandle->size())
    {
        SWARNING << "Cannot move the value of to index " << _ToIndex << ", on field " << TheFieldHandle->getDescription()->getName() 
                 << ", on FieldContianer of type " << _FC->getType().getName()
                 << " because that field has size " << TheFieldHandle->size() << std::endl;
        return;
    }

    if(TheFieldHandle->isPointerField())
    {
        EditMFieldHandle<FieldContainerPtrMFieldBase>* TheHandle(dynamic_cast<EditMFieldHandle<FieldContainerPtrMFieldBase>*>(TheFieldHandle.get()));
        FieldContainer* ToFC = TheHandle->get(_ToIndex);
        FieldContainer* FromFC = TheHandle->get(_FromIndex);

        TheHandle->replace(_FromIndex, ToFC);
        TheHandle->replace(_ToIndex, FromFC);
    }
    else
    {
        //Get the to index value
        std::ostringstream StrStream;
        OutStream TheOutStream(StrStream);

        TheFieldHandle->pushIndexedValueToStream(TheOutStream, _ToIndex);
        std::string ToValue = StrStream.str();

        //Get the from index value
        StrStream.clear();
        StrStream.str("");
        TheFieldHandle->pushIndexedValueToStream(TheOutStream, _FromIndex);
        std::string FromValue = StrStream.str();

        //Set the value
        TheFieldHandle->pushIndexedValueFromCString(ToValue.c_str(), _FromIndex);
        TheFieldHandle->pushIndexedValueFromCString(FromValue.c_str(), _ToIndex);
    }

    Inherited::execute();
	_HasBeenDone = true;
}
void InsertFieldElementCommand::execute(void)
{
    //Check for a valid Field Container
    if(_FC == NULL)
    {
        SWARNING << "FieldContainer is NULL." << std::endl;
        return;
    }

    //Check for valid Field
    EditFieldHandlePtr TheFieldHandle = _FC->editField(_FieldId);
    if(!TheFieldHandle->isValid())
    {
        SWARNING << "No Field with Id: " << _FieldId << " in FieldContainers of type " << _FC->getType().getName() << std::endl;
        return;
    }

    //Check for valid Field cardinality
    if(TheFieldHandle->getCardinality() != FieldType::MultiField)
    {
        SWARNING << "Field: " << _FC->getType().getName() << " is not a MultiField" << std::endl;
        return;
    }

    //Check for valid indexing
    if(TheFieldHandle->getCardinality() == FieldType::MultiField && _Index > TheFieldHandle->size())
    {
        SWARNING << "Cannot insert the value " << _Value << " at index " << _Index << ", on field " << TheFieldHandle->getDescription()->getName() 
                 << ", on FieldContianer of type " << _FC->getType().getName()
                 << " because that field has size " << TheFieldHandle->size() << std::endl;
        return;
    }
        
    if(TheFieldHandle->isPointerField())
    {
        EditMFieldHandle<FieldContainerPtrMFieldBase>* TheHandle(dynamic_cast<EditMFieldHandle<FieldContainerPtrMFieldBase>*>(TheFieldHandle.get()));
        FieldContainer* FC = FieldContainerFactory::the()->getContainer(boost::lexical_cast<UInt32>(_Value));
        //Check the pointer types match
        if(!isFieldContentDerivedFrom(TheFieldHandle->getType(),&FC->getType()))
        {
            SWARNING << "Cannot insert the value of field " << TheFieldHandle->getDescription()->getName() 
                     << ", on FieldContianer of type " << _FC->getType().getName()
                     << " because the value attemting to be set is not derived from the type the field stores." << std::endl;
            return;
        }

        TheHandle->insert(_Index, FC);
    }
    else
    {
        TheFieldHandle->insertIndexedValueFromCString(_Value.c_str(), _Index);
    }

    Inherited::execute();
	_HasBeenDone = true;
}
void InsertFieldElementCommand::undo(void)
{
    Inherited::undo();

    //Remove the element that was inserted
    EditFieldHandlePtr TheFieldHandle = _FC->editField(_FieldId); 
    if(TheFieldHandle->isPointerField())
    {
        EditMFieldHandle<FieldContainerPtrMFieldBase>* TheHandle(dynamic_cast<EditMFieldHandle<FieldContainerPtrMFieldBase>*>(TheFieldHandle.get()));

        TheHandle->remove(_Index);
    }
    else
    {
        TheFieldHandle->removeIndex(_Index);
    }
}
void InsertFieldElementCommand::redo(void)
{
    Inherited::redo();

    //Set the value
    EditFieldHandlePtr TheFieldHandle = _FC->editField(_FieldId);
    if(TheFieldHandle->isPointerField())
    {
        EditMFieldHandle<FieldContainerPtrMFieldBase>* TheHandle(dynamic_cast<EditMFieldHandle<FieldContainerPtrMFieldBase>*>(TheFieldHandle.get()));
        FieldContainer* FC = FieldContainerFactory::the()->getContainer(boost::lexical_cast<UInt32>(_Value));

        TheHandle->insert(_Index, FC);
    }
    else
    {
        TheFieldHandle->insertIndexedValueFromCString(_Value.c_str(), _Index);
    }
}
void GenericMultiFieldEditor::insertAtIndex(FieldContainer* const fc,
                                            UInt32 fieldID,
                                            UInt32 index,
                                            const FieldContainerType* type,
                                            CommandManager* cmdMgr)
{
    const FieldContainerType* ThePtrType(getFieldContainerTypeFromPtrType(fc->getFieldDescription(fieldID)->getFieldType().getContentType()));

    //Create the Container
    CreateFieldContainerCommandPtr CreateCommand;
    
    //If the type is a node, then create a NodeCore instead
    //and then insert it as the core of a newly created node
    if(*ThePtrType == Node::getClassType())
    {
        CreateFieldContainerCommandPtr CreateCoreCommand = CreateFieldContainerCommand::create(type);
        cmdMgr->executeCommand(CreateCoreCommand);
        
        CreateCommand = CreateFieldContainerCommand::create(&Node::getClassType());
        cmdMgr->executeCommand(CreateCommand);

        dynamic_cast<Node*>(CreateCommand->getContainer())->setCore(dynamic_cast<NodeCore*>(CreateCoreCommand->getContainer()));
    }
    else
    {
        CreateCommand = CreateFieldContainerCommand::create(type);
        cmdMgr->executeCommand(CreateCommand);
    }
        
    EditFieldHandlePtr TheFieldHandle = fc->editField(fieldID);
    EditMFieldHandle<FieldContainerPtrMFieldBase>* TheHandle(dynamic_cast<EditMFieldHandle<FieldContainerPtrMFieldBase>*>(TheFieldHandle.get()));

    if(index >= fc->getField(fieldID)->size() ||
       !TheHandle->supportsInsert())
    {
        //Set the value of the field
        AddFieldElementCommandPtr AddCommand = AddFieldElementCommand::create(fc,
                                                                            fieldID,
                                                                            boost::lexical_cast<std::string>(CreateCommand->getContainer()->getId()));

        cmdMgr->executeCommand(AddCommand);
    }
    else
    {
        //Set the value of the field
        InsertFieldElementCommandPtr InsertIndexCommand = InsertFieldElementCommand::create(fc,
                                                                                            fieldID,
                                                                                            boost::lexical_cast<std::string>(CreateCommand->getContainer()->getId()),
                                                                                            index);

        cmdMgr->executeCommand(InsertIndexCommand);
    }
}
void MoveFieldElementCommand::undo(void)
{
    Inherited::undo();

    EditFieldHandlePtr TheFieldHandle = _FC->editField(_FieldId);
    if(TheFieldHandle->isPointerField())
    {
        EditMFieldHandle<FieldContainerPtrMFieldBase>* TheHandle(dynamic_cast<EditMFieldHandle<FieldContainerPtrMFieldBase>*>(TheFieldHandle.get()));
        FieldContainerUnrecPtr ToFC = TheHandle->get(_ToIndex);
        TheHandle->remove(_ToIndex);
        TheHandle->insert(_FromIndex, ToFC);
    }
    else
    {
        //Get the to index value
        std::ostringstream StrStream;
        OutStream TheOutStream(StrStream);

        //Set the value
        if(_ToIndex < _FromIndex)
        {
            TheFieldHandle->pushIndexedValueToStream(TheOutStream, _ToIndex);
            TheFieldHandle->insertIndexedValueFromCString(StrStream.str().c_str(), _FromIndex+1);
        }
        else
        {
            TheFieldHandle->pushIndexedValueToStream(TheOutStream, _ToIndex-1);
            TheFieldHandle->insertIndexedValueFromCString(StrStream.str().c_str(), _FromIndex);
        }
        TheFieldHandle->removeIndex(_ToIndex);
    }

}