void MODULE::Copy( MODULE* aModule )
{
    m_Pos           = aModule->m_Pos;
    m_Layer         = aModule->m_Layer;
    m_fpid          = aModule->m_fpid;
    m_Attributs     = aModule->m_Attributs;
    m_ModuleStatus  = aModule->m_ModuleStatus;
    m_Orient        = aModule->m_Orient;
    m_BoundaryBox   = aModule->m_BoundaryBox;
    m_CntRot90      = aModule->m_CntRot90;
    m_CntRot180     = aModule->m_CntRot180;
    m_LastEditTime  = aModule->m_LastEditTime;
    m_Link          = aModule->m_Link;
    m_Path          = aModule->m_Path; //is this correct behavior?
    SetTimeStamp( GetNewTimeStamp() );

    m_LocalClearance                = aModule->m_LocalClearance;
    m_LocalSolderMaskMargin         = aModule->m_LocalSolderMaskMargin;
    m_LocalSolderPasteMargin        = aModule->m_LocalSolderPasteMargin;
    m_LocalSolderPasteMarginRatio   = aModule->m_LocalSolderPasteMarginRatio;
    m_ZoneConnection                = aModule->m_ZoneConnection;
    m_ThermalWidth                  = aModule->m_ThermalWidth;
    m_ThermalGap                    = aModule->m_ThermalGap;

    // Copy reference and value.
    m_Reference->Copy( aModule->m_Reference );
    m_Value->Copy( aModule->m_Value );

    // Copy auxiliary data: Pads
    m_Pads.DeleteAll();

    for( D_PAD* pad = aModule->m_Pads;  pad;  pad = pad->Next() )
    {
        D_PAD* newpad = new D_PAD( this );
        newpad->Copy( pad );
        m_Pads.PushBack( newpad );
    }

    // Copy auxiliary data: Drawings
    m_Drawings.DeleteAll();

    for( BOARD_ITEM* item = aModule->m_Drawings;  item;  item = item->Next() )
    {
        switch( item->Type() )
        {
        case PCB_MODULE_TEXT_T:
        {
            TEXTE_MODULE* textm = new TEXTE_MODULE( this );
            textm->Copy( static_cast<TEXTE_MODULE*>( item ) );
            m_Drawings.PushBack( textm );
            break;
        }

        case PCB_MODULE_EDGE_T:
        {
            EDGE_MODULE * edge;
            edge = new EDGE_MODULE( this );
            edge->Copy( (EDGE_MODULE*) item );
            m_Drawings.PushBack( edge );
            break;
        }

        default:
            wxLogMessage( wxT( "MODULE::Copy() Internal Err:  unknown type" ) );
            break;
        }
    }

    // Copy auxiliary data: 3D_Drawings info
    m_3D_Drawings.DeleteAll();

    // Ensure there is one (or more) item in m_3D_Drawings
    m_3D_Drawings.PushBack( new S3D_MASTER( this ) ); // push a void item

    for( S3D_MASTER* item = aModule->m_3D_Drawings;  item;  item = item->Next() )
    {
        if( item->GetShape3DName().IsEmpty() )           // do not copy empty shapes.
            continue;

        S3D_MASTER* t3d = m_3D_Drawings;

        if( t3d && t3d->GetShape3DName().IsEmpty() )    // The first entry can
        {                                               // exist, but is empty : use it.
            t3d->Copy( item );
        }
        else
        {
            t3d = new S3D_MASTER( this );
            t3d->Copy( item );
            m_3D_Drawings.PushBack( t3d );
        }
    }

    m_Doc     = aModule->m_Doc;
    m_KeyWord = aModule->m_KeyWord;

    // Ensure auxiliary data is up to date
    CalculateBoundingBox();
}
EDGE_MODULE * WinEDA_ModuleEditFrame::Begin_Edge_Module(EDGE_MODULE * Edge,
			wxDC * DC, int type_edge)
/*************************************************************************/

/* Fonction de debut de trace d'un nouveau contour.
	- Cree la place en memoire du nouveau contour
	- Prepare les coord des differents points
	- Met a jour la variable type_edge (= S_SEGMENT,S_ARC ...)
*/
{
MODULE* Module = m_Pcb->m_Modules;
int angle = 0;

	if ( Module == NULL )  return NULL;

	if(Edge == NULL )		/* debut reel du trace */
		{
		SaveCopyInUndoList();
		Edge = new EDGE_MODULE( Module );
		MoveVector.x = MoveVector.y = 0;

		/* Chainage du nouvel element, en tete de liste Drawings */
		Edge->Pback = Module;
		Edge->Pnext = Module->m_Drawings;
		if( Module->m_Drawings ) Module->m_Drawings->Pback = Edge;
		Module->m_Drawings = Edge;

		/* Mise a jour des caracteristiques du segment ou de l'arc */
		Edge->m_Flags = IS_NEW;
		Edge->m_Angle = angle;
		Edge->m_Shape = type_edge;
		if ( Edge->m_Shape == S_ARC ) Edge->m_Angle = ArcValue;
		Edge->m_Width = ModuleSegmentWidth;
		Edge->m_Layer = Module->m_Layer;
		if(Module->m_Layer == CMP_N) Edge->m_Layer = SILKSCREEN_N_CMP;
		if(Module->m_Layer == CUIVRE_N) Edge->m_Layer = SILKSCREEN_N_CU;
		/* Mise a jour du point de depart du segment ou de l'arc */
		Edge->m_Start = GetScreen()->m_Curseur;
		/* Mise a jour de la fin du segment , rectangle ou de l'arc*/
		Edge->m_End = Edge->m_Start;

		/* Mise a jour des coord relatives */
		Edge->m_Start0.x = Edge->m_Start.x - Module->m_Pos.x;
		Edge->m_Start0.y = Edge->m_Start.y - Module->m_Pos.y;
		RotatePoint((int*)&(Edge->m_Start0.x),
					(int*)&(Edge->m_Start0.y), - Module->m_Orient);
		Edge->m_End0 = Edge->m_Start0;
		Module->Set_Rectangle_Encadrement();

		GetScreen()->ManageCurseur = ShowEdgeModule;
		GetScreen()->ForceCloseManageCurseur = Exit_EditEdge_Module;
		}

	else	/* trace en cours : les coord du point d'arrivee ont ete mises
				a jour par la routine Montre_Position_New_Edge_Module*/
		{
		if( type_edge == S_SEGMENT )
			{
			if( (Edge->m_Start0.x) != (Edge->m_End0.x) ||
				(Edge->m_Start0.y) != (Edge->m_End0.y) )
				{
				GetScreen()->Trace_Curseur(DrawPanel, DC);
				Edge->Draw(DrawPanel, DC, wxPoint(0, 0), GR_OR);
				GetScreen()->Trace_Curseur(DrawPanel, DC);
				EDGE_MODULE * newedge = new EDGE_MODULE(Module);
				newedge->Copy(Edge);
				newedge->AddToChain(Edge);
				Edge->m_Flags = 0;
				Edge = newedge;

				Edge->m_Flags = IS_NEW;
				Edge->m_Width = ModuleSegmentWidth;
				Edge->m_Start = GetScreen()->m_Curseur;
				Edge->m_End = Edge->m_Start;

				 /* Mise a jour des coord relatives */
				Edge->m_Start0.x = Edge->m_Start.x - Module->m_Pos.x;
				Edge->m_Start0.y = Edge->m_Start.y - Module->m_Pos.y;
				RotatePoint((int*)&(Edge->m_Start0.x),
							(int*)&(Edge->m_Start0.y), -Module->m_Orient);
				Edge->m_End0 = Edge->m_Start0;

				Module->Set_Rectangle_Encadrement();
				Module->m_LastEdit_Time = time(NULL);
				GetScreen()->SetModify();
				}
			}
		else
			DisplayError(this, wxT("Begin_Edge() error"));
		}
	return Edge;
}